]> code.delx.au - gnu-emacs/commitdiff
Merge from origin/emacs-25
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 18 Jun 2016 22:47:00 +0000 (00:47 +0200)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 18 Jun 2016 22:47:00 +0000 (00:47 +0200)
9ae514a * etc/AUTHORS: Update the AUTHORS file
3ca428e add entries to authors.el
66d556b Fix eldoc-related freezes in python mode
d59bcbc Handle mouse leaving initial window in `mouse-set-region' (Bu...
27fe1e4 org.el: Fix bindings of < and > for calendar scrolling
a813487 Fix undo boundary in recursive edit (Bug#23632)
1f85b7c Doc fixes re alist-get.  (Bug#23548)
ba3f206 * lisp/progmodes/python.el (inferior-python-mode): Avoid tabs...
56fa055 * src/syntax.c (syms_of_syntax) <comment-end-can-be-escaped>:...
4c1370a * lisp/help-fns.el (describe-function-1): Fix handling of fil...
a3f7ae8 * lisp/emacs-lisp/cl-macs.el (cl-loop): Doc fix re "by".
601b9b2 * doc/misc/cl.texi (Mapping over Sequences): Fix cl-notevery.

1  2 
etc/NEWS
lisp/emacs-lisp/cl-macs.el
lisp/help-fns.el
lisp/mouse.el
lisp/org/org.el
lisp/progmodes/python.el
lisp/simple.el
lisp/subr.el
src/keyboard.c
src/syntax.c
test/lisp/simple-tests.el

diff --combined etc/NEWS
index d8583cf5ab81c248e1804c0974cf429b2b9a23b0,56074cebdf9d07ec5ea1dbdf1c74de229bb555f8..b3a044d4cd2bf01479b568959083b96c8bc363cd
+++ b/etc/NEWS
@@@ -22,503 -22,6 +22,503 @@@ Temporary note
  When you add a new item, use the appropriate mark if you are sure it applies,
  otherwise leave it unmarked.
  
 +\f
 +* Installation Changes in Emacs 25.2
 +
 +** The new option 'configure --enable-gcc-warnings=warn-only' causes
 +GCC to issue warnings without stopping the build.  This behavior is
 +now the default in developer builds.  As before, use
 +'--disable-gcc-warnings' to suppress GCC's warnings, and
 +'--enable-gcc-warnings' to stop the build if GCC issues warnings.
 +
 ++++
 +** The Emacs server now has socket-launching support.  This allows
 +socket based activation, where an external process like systemd can
 +invoke the Emacs server process upon a socket connection event and
 +hand the socket over to Emacs.  Emacs uses this socket to service
 +emacsclient commands.  This new functionality can be disabled with the
 +configure option '--disable-libsystemd'.
 +
 +** New configure option '--disable-build-details' attempts to build an
 +Emacs that is more likely to be reproducible; that is, if you build
 +and install Emacs twice, the second Emacs is a copy of the first.
 +Deterministic builds omit the build date from the output of the
 +emacs-version and erc-cmd-SV functions, and the leave the following
 +variables nil: emacs-build-system, emacs-build-time,
 +erc-emacs-build-time.
 +
 +** Emacs no longer works on IRIX.  We expect that Emacs users are not
 +affected by this, as SGI stopped supporting IRIX in December 2013.
 +
 +\f
 +* Startup Changes in Emacs 25.2
 +
 +\f
 +* Changes in Emacs 25.2
 +
 +---
 +** 'find-library-name' will now fall back on looking at 'load-history'
 +to try to locate libraries that have been loaded with an explicit path
 +outside 'load-path'.
 +
 ++++
 +** Faces in 'minibuffer-prompt-properties' no longer overwrite properties
 +in the text in functions like 'read-from-minibuffer', but instead are
 +added to the end of the face list.  This allows users to say things
 +like '(read-from-minibuffer (propertize "Enter something: " 'face 'bold))'.
 +
 ++++
 +** The new variable 'extended-command-suggest-shorter' has been added
 +to control whether to suggest shorter 'M-x' commands or not.
 +
 +---
 +** icomplete now respects 'completion-ignored-extensions'.
 +
 ++++
 +** Non-breaking hyphens are now displayed with the 'nobreak-hyphen'
 +face instead of the 'escape-glyph' face.
 +
 +---
 +** 'C-x h' ('mark-whole-buffer') will now avoid marking the prompt
 +part of minibuffers.
 +
 +---
 +** 'find-library' now takes a prefix argument to pop to a different
 +window.
 +
 +** 'find-library', 'help-function-def' and 'help-variable-def' now run
 +'find-function-after-hook'.
 +
 +---
 +** 'process-attributes' on Darwin systems now returns more information.
 +
 ++++
 +** Several accessors for the value returned by 'file-attributes'
 +have been added.  They are: 'file-attribute-type',
 +'file-attribute-link-number', 'file-attribute-user-id',
 +'file-attribute-group-id', 'file-attribute-access-time',
 +'file-attribute-modification-time',
 +'file-attribute-status-change-time', 'file-attribute-size',
 +'file-attribute-modes', 'file-attribute-inode-number', and
 +'file-attribute-device-number'.
 +
 ++++
 +** The new function 'buffer-hash' computes a fast, non-consing hash of
 +a buffer's contents.
 +
 +---
 +** 'fill-paragraph' no longer marks the buffer as changed unless it
 +actually changed something.
 +
 +---
 +** The locale language name 'ca' is now mapped to the language
 +environment 'Catalan', which has been added.
 +
 +---
 +** 'align-regexp' has a separate history for its interactive argument.
 +'align-regexp' no longer shares its history with all other
 +history-less functions that use 'read-string'.
 +
 ++++
 +** The networking code has been reworked so that it's more
 +asynchronous than it was (when specifying :nowait t in
 +'make-network-process').  How asynchronous it is varies based on the
 +capabilities of the system, but on a typical GNU/Linux system the DNS
 +resolution, the connection, and (for TLS streams) the TLS negotiation
 +are all done without blocking the main Emacs thread.  To get
 +asynchronous TLS, the TLS boot parameters have to be passed in (see
 +the manual for details).
 +
 +Certain process oriented functions (like 'process-datagram-address')
 +will block until socket setup has been performed.  The recommended way
 +to deal with asynchronous sockets is to avoid interacting with them
 +until they have changed status to "run".  This is most easily done
 +from a process sentinel.
 +
 +** 'make-network-process' and 'open-network-stream' sometimes allowed
 +:service to be an integer string (e.g., :service "993") and sometimes
 +required an integer (e.g., :service 993).  This difference has been
 +eliminated, and integer strings work everywhere.
 +
 +** It is possible to disable attempted recovery on fatal signals.
 +
 +Two new variables support disabling attempts to recover from stack
 +overflow and to avoid automatic auto-save when Emacs is delivered a
 +fatal signal.  'attempt-stack-overflow-recovery', if set to 'nil',
 +will disable attempts to recover from C stack overflows; Emacs will
 +then crash as with any other fatal signal.
 +'attempt-orderly-shutdown-on-fatal-signal', if set to 'nil', will
 +disable attempts to auto-save the session and shut down in an orderly
 +fashion when Emacs receives a fatal signal; instead, Emacs will
 +terminate immediately.  Both variables are non-'nil' by default.
 +These variables are for users who would like to avoid the small
 +probability of data corruption due to techniques Emacs uses to recover
 +in these situations.
 +
 ++++
 +** File local and directory local variables are now initialized each
 +time the major mode is set, not just when the file is first visited.
 +These local variables will thus not vanish on setting a major mode.
 +
 ++++
 +** A second dir-local file (.dir-locals-2.el) is now accepted.
 +See the variable 'dir-locals-file-2' for more information.
 +
 +---
 +** International domain names (IDNA) are now encoded via the new
 +puny.el library, so that one can visit web sites with non-ASCII URLs.
 +
 ++++
 +** The new 'timer-list' command lists all active timers in a buffer,
 +where you can cancel them with the 'c' command.
 +
 ++++
 +** The new function 'read-multiple-choice' prompts for multiple-choice
 +questions, with a handy way to display help texts.
 +
 ++++
 +** 'switch-to-buffer-preserve-window-point' now defaults to t.
 +
 +\f
 +* Editing Changes in Emacs 25.2
 +
 ++++
 +** New bindings for 'query-replace-map'.
 +'undo', undo the last replacement; bound to 'u'.
 +'undo-all', undo all replacements; bound to 'U'.
 +
 +\f
 +* Changes in Specialized Modes and Packages in Emacs 25.2
 +
 +** Compilation mode
 +
 +---
 +*** Messages from CMake are now recognized.
 +
 +** Dired
 +
 ++++
 +*** In wdired, when editing files to contain slash characters,
 +the resulting directories are automatically created.  Whether to do
 +this is controlled by the 'wdired-create-parent-directories' variable.
 +
 ++++
 +*** 'W' is now bound to 'browse-url-of-dired-file', and is useful for
 +viewing HTML files and the like.
 +
 +** Ediff
 +
 +*** Ediff can be prevented from pausing 1 second after reaching a
 +breakpoint (e.g. with "f" and "o") by customizing the new option
 +'edebug-sit-on-break'.
 +
 +** eww
 +
 ++++
 +*** A new 's' command for switching to another eww buffer via the minibuffer.
 +
 +---
 +*** The 'o' command ('shr-save-contents') has moved to 'O' to avoid collision
 +with the 'o' command from 'image-map'.
 +
 ++++
 +*** A new command 'C' ('eww-toggle-colors') can be used to toggle
 +whether to use the HTML-specified colors or not.  The user can also
 +customize the 'shr-use-colors' variable.
 +
 +---
 +*** Images that are being loaded are now marked with gray
 +"placeholder" images of the size specified by the HTML.  They are then
 +replaced by the real images asynchronously, which will also now
 +respect width/height HTML specs (unless they specify widths/heights
 +bigger than the current window).
 +
 +** Images
 +
 ++++
 +*** Images are automatically scaled before displaying based on the
 +'image-scaling-factor' variable (if Emacs supports scaling the images
 +in question).
 +
 ++++
 +*** Images inserted with 'insert-image' and related functions get a
 +keymap put into the text properties (or overlays) that span the
 +image.  This keymap binds keystrokes for manipulating size and
 +rotation, as well as saving the image to a file.  These commands are
 +also available in 'image-mode'.
 +
 ++++
 +*** A new library for creating and manipulating SVG images has been
 +added.  See the "SVG Images" section in the lispref manual for
 +details.
 +
 ++++
 +*** New setf-able function to access and set image parameters is
 +provided: 'image-property'.
 +
 +---
 +** The default 'Info-default-directory-list' no longer checks some obsolete
 +directory suffixes (gnu, gnu/lib, gnu/lib/emacs, emacs, lib, lib/emacs)
 +when searching for info directories.
 +
 ++++
 +** The commands that add ChangeLog entries now prefer a VCS root directory
 +for the ChangeLog file, if none already exists.  Customize
 +'change-log-directory-files' to nil for the old behavior.
 +
 +---
 +** Support for non-string values of 'time-stamp-format' has been removed.
 +
 +** Message
 +
 +---
 +*** 'message-use-idna' now defaults to t (because Emacs comes with
 +built-in IDNA support now).
 +
 +---
 +*** When sending HTML messages with embedded images, and you have
 +exiftool installed, and you rotate images with EXIF data (i.e.,
 +JPEGs), the rotational information will be inserted into the outgoing
 +image in the message.  (The original image will not have its
 +orientation affected.)
 +
 +---
 +*** The 'message-valid-fqdn-regexp' variable has been removed, since
 +there are now top-level domains added all the time.  Message will no
 +longer warn about sending emails to top-level domains it hasn't heard
 +about.
 +
 +*** 'message-beginning-of-line' (bound to C-a) understands folded headers.
 +In 'visual-line-mode' it will look for the true beginning of a header
 +while in non-'visual-line-mode' it will move the point to the indented
 +header's value.
 +
 +** Tramp
 +
 ++++
 +*** New connection method "sg", which supports editing files under a
 +different group ID.
 +
 ++++
 +*** New connection method "doas" for OpenBSD hosts.
 +
 +---
 +** 'auto-revert-use-notify' is set back to t in 'global-auto-revert-mode'.
 +
 +** CSS mode
 +
 +---
 +*** Support for completing attribute values, at-rules, bang-rules, and
 +HTML tags using the 'completion-at-point' command.
 +
 ++++
 +** Emacs now supports character name escape sequences in character and
 +string literals.  The syntax variants \N{character name} and
 +\N{U+code} are supported.
 +
 ++++
 +** Prog mode has some support for multi-mode indentation.
 +This allows better indentation support in modes that support multiple
 +programming languages in the same buffer, like literate programming
 +environments or ANTLR programs with embedded Python code.
 +
 +A major mode can provide indentation context for a sub-mode through
 +the 'prog-indentation-context' variable.  To support this, modes that
 +provide indentation should use 'prog-widen' instead of 'widen' and
 +'prog-first-column' instead of a literal zero.  See the node
 +"Mode-Specific Indent" in the ELisp manual for more details.
 +
 +** ERC
 +
 +*** New variable 'erc-default-port-tls' used to connect to TLS IRC
 +servers.
 +
 +** URL
 +
 ++++
 +*** The new function 'url-cookie-delete-cookie' can be used to
 +programmatically delete all cookies, or cookies from a specific
 +domain.
 +
 ++++
 +*** 'url-retrieve-synchronously' now takes an optional timeout parameter.
 +
 +---
 +*** The URL package now support HTTPS over proxies supporting CONNECT.
 +
 ++++
 +*** 'url-user-agent' now defaults to 'default', and the User-Agent
 +string is computed dynamically based on 'url-privacy-level'.
 +
 +** VC and related modes
 +
 +---
 +*** The VC state indicator in the mode line now defaults to more
 +colorful faces to make it more obvious to the user what the state is.
 +See the 'vc-faces' customization group.
 +
 +** CC mode
 +
 +*** Opening a .h file will turn C or C++ mode depending on language used.
 +This is done with the help of 'c-or-c++-mode' function which analyses
 +contents of the buffer to determine whether it's a C or C++ source
 +file.
 +
 +\f
 +* New Modes and Packages in Emacs 25.2
 +
 +** New Elisp data-structure library `radix-tree'.
 +
 +\f
 +* Incompatible Lisp Changes in Emacs 25.2
 +
 ++++
 +** Resizing a frame no longer runs 'window-configuration-change-hook'.
 +Put your function on 'window-size-change-functions' instead.
 +
 +** 'C-up', 'C-down', 'C-left' and 'C-right' are now defined in term
 +mode to send the same escape sequences that xterm does.  This makes
 +things like forward-word in readline work.
 +
 +---
 +** hideshow mode got four key bindings that are analogous to outline
 +mode bindings: 'C-c @ C-a', 'C-c @ C-t', 'C-c @ C-d', and 'C-c @ C-e.'
 +
 +** The grep/rgrep/lgrep functions will now ask about saving files
 +before running.  This is controlled by the 'grep-save-buffers'
 +variable.
 +
 ++++
 +** The variable 'text-quoting-style' no longer affects the treatment
 +of curved quotes in format arguments to functions like 'message' and
 +'format-message'.  In particular, when this variable's value is
 +'grave', all quotes in formats are output as-is.
 +
 +** Functions like 'check-declare-file' and 'check-declare-directory'
 +now generate less chatter and more-compact diagnostics.  The auxiliary
 +function 'check-declare-errmsg' has been removed.
 +
 +\f
 +* Lisp Changes in Emacs 25.2
 +
 +** New var `definition-prefixes' is a hashtable mapping prefixes to the
 +files where corresponding definitions can be found.  This can be used
 +to fetch definitions that are not yet loaded, for example for `C-h f'.
 +
 +** New var syntax-ppss-table to control the syntax-table used in syntax-ppss.
 +
 ++++
 +** 'define-derived-mode' can now specify an :after-hook form, which
 +gets evaluated after the new mode's hook has run.  This can be used to
 +incorporate configuration changes made in the mode hook into the
 +mode's setup.
 +
 +** Autoload files can be generated without timestamps,
 +by setting 'autoload-timestamps' to nil.
 +FIXME As an experiment, nil is the current default.
 +If no insurmountable problems before next release, it can stay that way.
 +
 +---
 +** 'gnutls-boot' now takes a parameter :complete-negotiation that says
 +that negotiation should complete even on non-blocking sockets.
 +
 ++++
 +** New functions 'window-pixel-width-before-size-change' and
 +'window-pixel-height-before-size-change' support detecting which
 +window changed size when 'window-size-change-functions' are run.
 +
 ++++
 +** New function 'display-buffer-reuse-mode-window' is an action function
 +suitable for use in 'display-buffer-alist'. For example, to avoid creating
 +a new window when opening man pages when there's already one, use
 +(add-to-list 'display-buffer-alist
 +     '("\\`\\*Man .*\\*\\'" .
 +       (display-buffer-reuse-mode-window
 +        (inhibit-same-window . nil)
 +        (mode . Man-mode))))
 +
 +---
 +** There is now a new variable 'flyspell-sort-corrections-function'
 +that allows changing the way corrections are sorted.
 +
 +---
 +** The new command 'fortune-message' has been added, which displays
 +fortunes in the echo area.
 +
 ++++
 +** New function 'func-arity' returns information about the argument list
 +of an arbitrary function.  This generalizes 'subr-arity' for functions
 +that are not built-in primitives.  We recommend using this new
 +function instead of 'subr-arity'.
 +
 ++++
 +** 'parse-partial-sexp' state has a new element.  Element 10 is
 +non-nil when the last character scanned might be the first character
 +of a two character construct, i.e., a comment delimiter or escaped
 +character.  Its value is the syntax of that last character.
 +
 ++++
 +** 'parse-partial-sexp''s state, element 9, has now been confirmed as
 +permanent and documented, and may be used by Lisp programs.  Its value
 +is a list of currently open parenthesis positions, starting with the
 +outermost parenthesis.
 +
 +---
 +** 'read-color' will now display the color names using the color itself
 +as the background color.
 +
 +** The function 'redirect-debugging-output' now works on platforms
 +other than GNU/Linux.
 +
 ++++
 +** The new function 'string-version-lessp' compares strings by
 +interpreting consecutive runs of numerical characters as numbers, and
 +compares their numerical values.  According to this predicate,
 +"foo2.png" is smaller than "foo12.png".
 +
 ++++
 +** The new function 'char-from-name' converts a Unicode name string
 +to the corresponding character code.
 +
 ++++
 +** New functions 'sxhash-eq' and 'sxhash-eql' return hash codes of a
 +Lisp object suitable for use with 'eq' and 'eql' correspondingly.  If
 +two objects are 'eq' ('eql'), then the result of 'sxhash-eq'
 +('sxhash-eql') on them will be the same.
 +
 ++++
 +** Function 'sxhash' has been renamed to 'sxhash-equal' for
 +consistency with the new functions.  For compatibility, 'sxhash'
 +remains as an alias to 'sxhash-equal'.
 +
 ++++
 +** Time conversion functions that accept a time zone rule argument now
 +allow it to be OFFSET or a list (OFFSET ABBR), where the integer
 +OFFSET is a count of seconds east of Universal Time, and the string
 +ABBR is a time zone abbreviation.  The affected functions are
 +'current-time-string', 'current-time-zone', 'decode-time',
 +'format-time-string', and 'set-time-zone-rule'.
 +
 ++++
 +*** New basic face 'fixed-pitch-serif', for a fixed-width font with serifs.
 +The Info-quoted and tex-verbatim faces now default to inheriting from it.
 +
 +\f
 +* Changes in Emacs 25.2 on Non-Free Operating Systems
 +
 +** Intercepting hotkeys on Windows 7 and later now works better.
 +The new keyboard hooking code properly grabs system hotkeys such as
 +Win-* and Alt-TAB, in a way that Emacs can get at them before the
 +system.  This makes the 'w32-register-hot-key' functionality work
 +again on all versions of MS-Windows starting with Windows 7.  On
 +Windows NT and later you can now register any hotkey combination.  (On
 +Windows 9X, the previous limitations, spelled out in the Emacs manual,
 +still apply.)
 +
 +** 'convert-standard-filename' no longer mirrors slashes on MS-Windows.
 +Previously, on MS-Windows this function converted slash characters in
 +file names into backslashes.  It no longer does that.
 +
  \f
  * Installation Changes in Emacs 25.1
  
@@@ -2177,7 -1680,8 +2177,8 @@@ codeset is "UTF-8" (as in "en_US.UTF-8"
  MS-Windows doesn't support UTF-8 as codeset in its locales.
  
  +++
- ** New function 'alist-get', which is also a valid place (aka lvalue).
+ ** New function 'alist-get', which is a generalized variable
+ suitable for use with 'setf'.
  
  +++
  ** New function 'funcall-interactively', which works like 'funcall'
index 121738df576b522595401e5f367f6ab8b40737e1,2cb821edcd395e853e5543b6758ee1d1d46a6f30..d2c90c2b8091a74dd6c0101073480e95d97bbafd
@@@ -851,9 -851,9 +851,9 @@@ This is compatible with Common Lisp, bu
    "The Common Lisp `loop' macro.
  Valid clauses include:
    For clauses:
-     for VAR from/upfrom/downfrom EXPR1 to/upto/downto/above/below EXPR2 by EXPR3
+     for VAR from/upfrom/downfrom EXPR1 to/upto/downto/above/below EXPR2 [by EXPR3]
      for VAR = EXPR1 then EXPR2
-     for VAR in/on/in-ref LIST by FUNC
+     for VAR in/on/in-ref LIST [by FUNC]
      for VAR across/across-ref ARRAY
      for VAR being:
        the elements of/of-ref SEQUENCE [using (index VAR2)]
@@@ -2672,11 -2672,7 +2672,11 @@@ non-nil value, that slot cannot be set 
            (let ((accessor (intern (format "%s%s" conc-name slot))))
              (push slot slots)
              (push (nth 1 desc) defaults)
 +            ;; The arg "cl-x" is referenced by name in eg pred-form
 +            ;; and pred-check, so changing it is not straightforward.
              (push `(cl-defsubst ,accessor (cl-x)
 +                       ,(format "Access slot \"%s\" of `%s' struct CL-X."
 +                                slot struct)
                         (declare (side-effect-free t))
                         ,@(and pred-check
                              (list `(or ,pred-check
diff --combined lisp/help-fns.el
index e92019f9345029cb533d236d617a81c62416f74a,496deb5c4f1cca4be80599cb9b6015848bb93c4c..97c8df2298aef6768f8a44b171852217921a24b0
@@@ -34,7 -34,6 +34,7 @@@
  
  (require 'cl-lib)
  (require 'help-mode)
 +(require 'radix-tree)
  
  (defvar help-fns-describe-function-functions nil
    "List of functions to run in help buffer in `describe-function'.
@@@ -44,61 -43,6 +44,61 @@@ The functions will receive the functio
  
  ;; Functions
  
 +(defvar help-definition-prefixes nil
 +  ;; FIXME: We keep `definition-prefixes' as a hash-table so as to
 +  ;; avoid pre-loading radix-tree and because it takes slightly less
 +  ;; memory.  But when we use this table it's more efficient to
 +  ;; represent it as a radix tree, since the main operation is to do
 +  ;; `radix-tree-prefixes'.  Maybe we should just bite the bullet and
 +  ;; use a radix tree for `definition-prefixes' (it's not *that*
 +  ;; costly, really).
 +  "Radix-tree representation replacing `definition-prefixes'.")
 +
 +(defun help-definition-prefixes ()
 +  "Return the up-to-date radix-tree form of `definition-prefixes'."
 +  (when (> (hash-table-count definition-prefixes) 0)
 +    (maphash (lambda (prefix files)
 +               (let ((old (radix-tree-lookup help-definition-prefixes prefix)))
 +                 (setq help-definition-prefixes
 +                       (radix-tree-insert help-definition-prefixes
 +                                          prefix (append old files)))))
 +             definition-prefixes)
 +    (clrhash definition-prefixes))
 +  help-definition-prefixes)
 +
 +(defun help--loaded-p (file)
 +  "Try and figure out if FILE has already been loaded."
 +  (or (let ((feature (intern-soft file)))
 +        (and feature (featurep feature)))
 +      (let* ((re (load-history-regexp file))
 +             (done nil))
 +        (dolist (x load-history)
 +          (if (string-match-p re (car x)) (setq done t)))
 +        done)))
 +
 +(defun help--load-prefixes (prefixes)
 +  (pcase-dolist (`(,prefix . ,files) prefixes)
 +    (setq help-definition-prefixes
 +          (radix-tree-insert help-definition-prefixes prefix nil))
 +    (dolist (file files)
 +      ;; FIXME: Should we scan help-definition-prefixes to remove
 +      ;; other prefixes of the same file?
 +      ;; FIXME: this regexp business is not good enough: for file
 +      ;; `toto', it will say `toto' is loaded when in reality it was
 +      ;; just cedet/semantic/toto that has been loaded.
 +      (unless (help--loaded-p file)
 +        (load file 'noerror 'nomessage)))))
 +
 +(defun help--symbol-completion-table (string pred action)
 +  (let ((prefixes (radix-tree-prefixes (help-definition-prefixes) string)))
 +    (help--load-prefixes prefixes))
 +  (let ((prefix-completions
 +         (mapcar #'intern (all-completions string definition-prefixes))))
 +    (complete-with-action action obarray string
 +                          (if pred (lambda (sym)
 +                                     (or (funcall pred sym)
 +                                         (memq sym prefix-completions)))))))
 +
  (defvar describe-function-orig-buffer nil
    "Buffer that was current when `describe-function' was invoked.
  Functions on `help-fns-describe-function-functions' can use this
@@@ -114,9 -58,8 +114,9 @@@ to get buffer-local values."
       (setq val (completing-read (if fn
                                    (format "Describe function (default %s): " fn)
                                  "Describe function: ")
 -                              obarray 'fboundp t nil nil
 -                              (and fn (symbol-name fn))))
 +                              #'help--symbol-completion-table
 +                                #'fboundp
 +                                t nil nil (and fn (symbol-name fn))))
       (list (if (equal val "")
               fn (intern val)))))
    (or (and function (symbolp function))
@@@ -583,7 -526,8 +583,8 @@@ FILE is the file where FUNCTION was pro
         (sig-key (if (subrp def)
                        (indirect-function real-def)
                      real-def))
-        (file-name (find-lisp-object-file-name function def))
+        (file-name (find-lisp-object-file-name function (if aliased 'defun
+                                                            def)))
           (pt1 (with-current-buffer (help-buffer) (point)))
         (beg (if (and (or (byte-code-function-p def)
                           (keymapp def)
      ;; Print what kind of function-like object FUNCTION is.
      (princ (cond ((or (stringp def) (vectorp def))
                  "a keyboard macro")
 -               ((subrp def)
 -                (if (eq 'unevalled (cdr (subr-arity def)))
 -                    (concat beg "special form")
 -                  (concat beg "built-in function")))
                 ;; Aliases are Lisp functions, so we need to check
                 ;; aliases before functions.
                 (aliased
                  (format-message "an alias for `%s'" real-def))
 +               ((subrp def)
 +                (if (eq 'unevalled (cdr (subr-arity def)))
 +                    (concat beg "special form")
 +                  (concat beg "built-in function")))
                 ((autoloadp def)
                  (format "%s autoloaded %s"
                          (if (commandp def) "an interactive" "an")
@@@ -756,23 -700,17 +757,23 @@@ it is displayed along with the global v
    (interactive
     (let ((v (variable-at-point))
         (enable-recursive-minibuffers t)
 +         (orig-buffer (current-buffer))
         val)
 -     (setq val (completing-read (if (symbolp v)
 -                                  (format
 -                                   "Describe variable (default %s): " v)
 -                                "Describe variable: ")
 -                              obarray
 -                              (lambda (vv)
 -                                  (or (get vv 'variable-documentation)
 -                                      (and (boundp vv) (not (keywordp vv)))))
 -                              t nil nil
 -                              (if (symbolp v) (symbol-name v))))
 +     (setq val (completing-read
 +                (if (symbolp v)
 +                    (format
 +                     "Describe variable (default %s): " v)
 +                  "Describe variable: ")
 +                #'help--symbol-completion-table
 +                (lambda (vv)
 +                  ;; In case the variable only exists in the buffer
 +                  ;; the command we switch back to that buffer before
 +                  ;; we examine the variable.
 +                  (with-current-buffer orig-buffer
 +                    (or (get vv 'variable-documentation)
 +                        (and (boundp vv) (not (keywordp vv))))))
 +                t nil nil
 +                (if (symbolp v) (symbol-name v))))
       (list (if (equal val "")
               v (intern val)))))
    (let (file-name)
            (unless valvoid
              (with-current-buffer standard-output
                (setq val-start-pos (point))
 -              (princ "value is ")
 -              (let ((from (point))
 -                    (line-beg (line-beginning-position))
 +              (princ "value is")
 +              (let ((line-beg (line-beginning-position))
                      (print-rep
                       (let ((rep
                              (let ((print-quoted t))
                             (format-message "`%s'" rep)
                           rep))))
                  (if (< (+ (length print-rep) (point) (- line-beg)) 68)
 -                    (insert print-rep)
 +                    (insert " " print-rep)
                    (terpri)
                    (pp val)
 -                  (if (< (point) (+ 68 (line-beginning-position 0)))
 -                      (delete-region from (1+ from))
 -                    (delete-region (1- from) from)))
 +                    ;; Remove trailing newline.
 +                    (delete-char -1))
                  (let* ((sv (get variable 'standard-value))
                         (origval (and (consp sv)
                                       (condition-case nil
                                           (eval (car sv))
 -                                       (error :help-eval-error)))))
 +                                       (error :help-eval-error))))
 +                         from)
                    (when (and (consp sv)
                                 (not (equal origval val))
                                 (not (equal origval :help-eval-error)))
@@@ -972,35 -911,29 +973,35 @@@ if it is given a local binding.\n")))
                                              (buffer-file-name buffer)))
                                        (dir-locals-find-file
                                         (buffer-file-name buffer))))
 -                          (dir-file t))
 +                          (is-directory nil))
                      (princ (substitute-command-keys
                              "  This variable's value is directory-local"))
 -                    (if (null file)
 -                        (princ ".\n")
 -                      (princ ", set ")
 -                        (if (consp file) ; result from cache
 -                            ;; If the cache element has an mtime, we
 -                            ;; assume it came from a file.
 -                            (if (nth 2 file)
 -                                (setq file (expand-file-name
 -                                            dir-locals-file (car file)))
 -                              ;; Otherwise, assume it was set directly.
 -                              (setq file (car file)
 -                                    dir-file nil)))
 -                      (princ (substitute-command-keys
 -                                (if dir-file
 -                                    "by the file\n  `"
 -                                  "for the directory\n  `")))
 +                      (when (consp file) ; result from cache
 +                        ;; If the cache element has an mtime, we
 +                        ;; assume it came from a file.
 +                        (if (nth 2 file)
 +                            ;; (car file) is a directory.
 +                            (setq file (dir-locals--all-files (car file)))
 +                          ;; Otherwise, assume it was set directly.
 +                          (setq file (car file)
 +                                is-directory t)))
 +                      (if (null file)
 +                          (princ ".\n")
 +                        (princ ", set ")
 +                        (princ (substitute-command-keys
 +                                (cond
 +                                 (is-directory "for the directory\n  `")
 +                                 ;; Many files matched.
 +                                 ((and (consp file) (cdr file))
 +                                  (setq file (file-name-directory (car file)))
 +                                  (format "by one of the\n  %s files in the directory\n  `"
 +                                          dir-locals-file))
 +                                 (t (setq file (car file))
 +                                    "by the file\n  `"))))
                        (with-current-buffer standard-output
                          (insert-text-button
                           file 'type 'help-dir-local-var-def
 -                         'help-args (list variable file)))
 +                             'help-args (list variable file)))
                        (princ (substitute-command-keys "'.\n"))))
                  (princ (substitute-command-keys
                          "  This variable's value is file-local.\n"))))
@@@ -1166,13 -1099,7 +1167,13 @@@ BUFFER should be a buffer or a buffer n
        (if (or (not (vectorp docs)) (/= (length docs) 95))
          (error "Invalid first extra slot in this category table\n"))
        (with-current-buffer standard-output
 -      (insert "Legend of category mnemonics (see the tail for the longer description)\n")
 +        (setq-default help-button-cache (make-marker))
 +      (insert "Legend of category mnemonics ")
 +        (insert-button "(longer descriptions at the bottom)"
 +                       'action help-button-cache
 +                       'follow-link t
 +                       'help-echo "mouse-2, RET: show full legend")
 +        (insert "\n")
        (let ((pos (point)) (items 0) lines n)
          (dotimes (i 95)
            (if (aref docs i) (setq items (1+ items))))
                "character(s)\tcategory mnemonics\n"
                "------------\t------------------")
        (describe-vector table 'help-describe-category-set)
 +        (set-marker help-button-cache (point))
        (insert "Legend of category mnemonics:\n")
        (dotimes (i 95)
          (let ((elt (aref docs i)))
diff --combined lisp/mouse.el
index 0be17b48cacaceaa460bf502b1fabcc881f3c1c2,64ee796a681f5c04d178acab08835c569ff75ab6..8d727536e05e018b9b390006508d475697eff544
@@@ -97,44 -97,35 +97,44 @@@ Expects to be bound to `down-mouse-1' i
    (when (and mouse-1-click-follows-link
               (eq (if (eq mouse-1-click-follows-link 'double)
                       'double-down-mouse-1 'down-mouse-1)
 -                 (car-safe last-input-event))
 -             (mouse-on-link-p (event-start last-input-event))
 -             (or mouse-1-click-in-non-selected-windows
 -                 (eq (selected-window)
 -                     (posn-window (event-start last-input-event)))))
 -    (let ((timedout
 -           (sit-for (if (numberp mouse-1-click-follows-link)
 -                     (/ (abs mouse-1-click-follows-link) 1000.0)
 -                     0))))
 -      (if (if (and (numberp mouse-1-click-follows-link)
 -                   (>= mouse-1-click-follows-link 0))
 -              timedout (not timedout))
 -          nil
 -
 -        (let ((event (read-key))) ;Use read-key so it works for xterm-mouse-mode!
 -          (if (eq (car-safe event) (if (eq mouse-1-click-follows-link 'double)
 -                                       'double-mouse-1 'mouse-1))
 -              ;; Turn the mouse-1 into a mouse-2 to follow links.
 -              (let ((newup (if (eq mouse-1-click-follows-link 'double)
 -                                'double-mouse-2 'mouse-2)))
 -                ;; If mouse-2 has never been done by the user, it doesn't have
 -                ;; the necessary property to be interpreted correctly.
 -                (unless (get newup 'event-kind)
 -                  (put newup 'event-kind (get (car event) 'event-kind)))
 -                (push (cons newup (cdr event)) unread-command-events)
 -                ;; Don't change the down event, only the up-event (bug#18212).
 -                nil)
 -            (push event unread-command-events)
 -            nil))))))
 +                 (car-safe last-input-event)))
 +    (let ((action (mouse-on-link-p (event-start last-input-event))))
 +      (when (and action
 +                 (or mouse-1-click-in-non-selected-windows
 +                     (eq (selected-window)
 +                         (posn-window (event-start last-input-event)))))
 +        (let ((timedout
 +               (sit-for (if (numberp mouse-1-click-follows-link)
 +                            (/ (abs mouse-1-click-follows-link) 1000.0)
 +                          0))))
 +          (if (if (and (numberp mouse-1-click-follows-link)
 +                       (>= mouse-1-click-follows-link 0))
 +                  timedout (not timedout))
 +              nil
 +            ;; Use read-key so it works for xterm-mouse-mode!
 +            (let ((event (read-key)))
 +              (if (eq (car-safe event)
 +                      (if (eq mouse-1-click-follows-link 'double)
 +                          'double-mouse-1 'mouse-1))
 +                  (progn
 +                    ;; Turn the mouse-1 into a mouse-2 to follow links,
 +                    ;; but only if â€˜mouse-on-link-p’ hasn’t returned a
 +                    ;; string or vector (see its docstring).
 +                    (if (or (stringp action) (vectorp action))
 +                        (push (aref action 0) unread-command-events)
 +                      (let ((newup (if (eq mouse-1-click-follows-link 'double)
 +                                       'double-mouse-2 'mouse-2)))
 +                        ;; If mouse-2 has never been done by the user, it
 +                        ;; doesn't have the necessary property to be
 +                        ;; interpreted correctly.
 +                        (unless (get newup 'event-kind)
 +                          (put newup 'event-kind (get (car event) 'event-kind)))
 +                        (push (cons newup (cdr event)) unread-command-events)))
 +                    ;; Don't change the down event, only the up-event
 +                    ;; (bug#18212).
 +                    nil)
 +                (push event unread-command-events)
 +                nil))))))))
  
  (define-key key-translation-map [down-mouse-1]
    #'mouse--down-1-maybe-follows-link)
@@@ -164,7 -155,7 +164,7 @@@ items `Turn Off' and `Help'.
                (if (fboundp mm-fun)      ; bug#20201
                    `(keymap
                      ,indicator
 -                    (turn-off menu-item "Turn Off minor mode" ,mm-fun)
 +                    (turn-off menu-item "Turn off minor mode" ,mm-fun)
                      (help menu-item "Help for minor mode"
                            (lambda () (interactive)
                              (describe-function ',mm-fun)))))))
@@@ -575,7 -566,12 +575,12 @@@ command alters the kill ring or not.
    (mouse-minibuffer-check click)
    (select-window (posn-window (event-start click)))
    (let ((beg (posn-point (event-start click)))
-       (end (posn-point (event-end click)))
+         (end
+          (if (eq (posn-window (event-end click)) (selected-window))
+              (posn-point (event-end click))
+            ;; If the mouse ends up in any other window or on the menu
+            ;; bar, use `window-point' of selected window (Bug#23707).
+            (window-point)))
          (click-count (event-click-count click)))
      (let ((drag-start (terminal-parameter nil 'mouse-drag-start)))
        (when drag-start
diff --combined lisp/org/org.el
index 1d060f871fefdebe71691f5f4aa9702226f6e1e5,13e4a22213181c7e117c9197a2dc5c38c568e712..30ef5e83bddacf4d294a411849545de62589376e
@@@ -127,7 -127,7 +127,7 @@@ Stars are put in group 1 and the trimme
  
  (declare-function orgtbl-mode "org-table" (&optional arg))
  (declare-function org-clock-out "org-clock" (&optional switch-to-state fail-quietly at-time))
 -(declare-function org-beamer-mode "ox-beamer" ())
 +(declare-function org-beamer-mode "ox-beamer" (&optional prefix) t)
  (declare-function org-table-edit-field "org-table" (arg))
  (declare-function org-table-justify-field-maybe "org-table" (&optional new))
  (declare-function org-table-set-constants "org-table" ())
  (declare-function org-id-get-create "org-id" (&optional force))
  (declare-function org-id-find-id-file "org-id" (id))
  (declare-function org-tags-view "org-agenda" (&optional todo-only match))
 -(declare-function org-agenda-list "org-agenda" (&optional arg start-day span))
 +(declare-function org-agenda-list "org-agenda"
 +                  (&optional arg start-day span with-hour))
  (declare-function org-agenda-redo "org-agenda" (&optional all))
  (declare-function org-table-align "org-table" ())
  (declare-function org-table-begin "org-table" (&optional table-type))
  (declare-function org-element-interpret-data "org-element"
                  (data &optional parent))
  (declare-function org-element-map "org-element"
 -                (data types fun &optional info first-match no-recursion))
 +                  (data types fun &optional
 +                        info first-match no-recursion with-affiliated))
  (declare-function org-element-nested-p "org-element" (elem-a elem-b))
  (declare-function org-element-parse-buffer "org-element"
                  (&optional granularity visible-only))
@@@ -450,8 -448,7 +450,8 @@@ For export specific modules, see also `
  
  (defvar org-export--registered-backends) ; From ox.el.
  (declare-function org-export-derived-backend-p "ox" (backend &rest backends))
 -(declare-function org-export-backend-name "ox" (backend))
 +(declare-function org-export-backend-name "ox" (backend) t)
 +(declare-function org-export-backend-options "ox" (cl-x) t)
  (defcustom org-export-backends '(ascii html icalendar latex)
    "List of export back-ends that should be always available.
  
@@@ -4216,7 -4213,7 +4216,7 @@@ Normal means, no org-mode-specific cont
  (defvar mark-active)
  
  ;; Various packages
 -(declare-function calendar-absolute-from-iso    "cal-iso"    (date))
 +(declare-function calendar-iso-to-absolute      "cal-iso"    (date))
  (declare-function calendar-forward-day          "cal-move"   (arg))
  (declare-function calendar-goto-date            "cal-move"   (date))
  (declare-function calendar-goto-today           "cal-move"   ())
  (declare-function dired-get-filename "dired" (&optional localp no-error-if-not-filep))
  (defvar font-lock-unfontify-region-function)
  (declare-function iswitchb-read-buffer "iswitchb"
 -                  (prompt &optional default require-match start matches-set))
 +                  (prompt &optional
 +                          default require-match _predicate start matches-set))
  (defvar iswitchb-temp-buflist)
  (declare-function org-gnus-follow-link "org-gnus" (&optional group article))
  (defvar org-agenda-tags-todo-honor-ignore-options)
  (declare-function org-agenda-skip "org-agenda" ())
  (declare-function
   org-agenda-format-item "org-agenda"
 - (extra txt &optional level category tags dotime noprefix remove-re habitp))
 + (extra txt &optional level category tags dotime remove-re habitp))
  (declare-function org-agenda-new-marker "org-agenda" (&optional pos))
  (declare-function org-agenda-change-all-lines "org-agenda"
                  (newhead hdmarker &optional fixface just-this))
@@@ -5284,6 -5280,7 +5284,6 @@@ This variable is set by `org-before-cha
  
  ;; Other stuff we need.
  (require 'time-date)
 -(unless (fboundp 'time-subtract) (defalias 'time-subtract 'subtract-time))
  (require 'easymenu)
  (require 'overlay)
  
@@@ -5517,8 -5514,8 +5517,8 @@@ the rounding returns a past time.
            (apply 'encode-time
                   (append (list 0 (* r (floor (+ .5 (/ (float (nth 1 time)) r)))))
                           (nthcdr 2 time))))
 -      (if (and past (< (org-float-time (time-subtract (current-time) res)) 0))
 -        (seconds-to-time (- (org-float-time res) (* r 60)))
 +      (if (and past (< (float-time (time-subtract (current-time) res)) 0))
 +        (seconds-to-time (- (float-time res) (* r 60)))
        res))))
  
  (defun org-today ()
@@@ -8782,24 -8779,24 +8782,24 @@@ links.
               (if (or (re-search-forward org-ts-regexp end t)
                       (re-search-forward org-ts-regexp-both end t))
                   (org-time-string-to-seconds (match-string 0))
 -               (org-float-time now))))
 +               (float-time now))))
            ((= dcst ?c)
             (let ((end (save-excursion (outline-next-heading) (point))))
               (if (re-search-forward
                    (concat "^[ \t]*\\[" org-ts-regexp1 "\\]")
                    end t)
                   (org-time-string-to-seconds (match-string 0))
 -               (org-float-time now))))
 +               (float-time now))))
            ((= dcst ?s)
             (let ((end (save-excursion (outline-next-heading) (point))))
               (if (re-search-forward org-scheduled-time-regexp end t)
                   (org-time-string-to-seconds (match-string 1))
 -               (org-float-time now))))
 +               (float-time now))))
            ((= dcst ?d)
             (let ((end (save-excursion (outline-next-heading) (point))))
               (if (re-search-forward org-deadline-time-regexp end t)
                   (org-time-string-to-seconds (match-string 1))
 -               (org-float-time now))))
 +               (float-time now))))
            ((= dcst ?p)
             (if (re-search-forward org-priority-regexp (point-at-eol) t)
                 (string-to-char (match-string 2))
@@@ -8863,7 -8860,7 +8863,7 @@@ If WITH-CASE is non-nil, the sorting wi
            (lambda (x)
              (if (or (string-match org-ts-regexp x)
                      (string-match org-ts-regexp-both x))
 -                (org-float-time
 +                (float-time
                   (org-time-string-to-time (match-string 0 x)))
                0))
            comparefun (if (= dcst sorting-type) '< '>)))
@@@ -12042,6 -12039,8 +12042,6 @@@ This function can be used in a hook.
  
  ;;;; Completion
  
 -(declare-function org-export-backend-name "org-export" (cl-x))
 -(declare-function org-export-backend-options "org-export" (cl-x))
  (defun org-get-export-keywords ()
    "Return a list of all currently understood export keywords.
  Export keywords include options, block names, attributes and
@@@ -16297,10 -16296,10 +16297,10 @@@ So these are more for recording a certa
                    (message "")))
      (org-defkey map ">"
                  (lambda () (interactive)
-                   (org-eval-in-calendar '(scroll-calendar-left 1))))
+                   (org-eval-in-calendar '(calendar-scroll-left 1))))
      (org-defkey map "<"
                  (lambda () (interactive)
-                   (org-eval-in-calendar '(scroll-calendar-right 1))))
+                   (org-eval-in-calendar '(calendar-scroll-right 1))))
      (org-defkey map "\C-v"
                  (lambda () (interactive)
                    (org-eval-in-calendar
@@@ -16887,7 -16886,7 +16887,7 @@@ Don't touch the rest.
  (defun org-time-stamp-to-now (timestamp-string &optional seconds)
    "Difference between TIMESTAMP-STRING and now in days.
  If SECONDS is non-nil, return the difference in seconds."
 -  (let ((fdiff (if seconds 'org-float-time 'time-to-days)))
 +  (let ((fdiff (if seconds 'float-time 'time-to-days)))
      (- (funcall fdiff (org-time-string-to-time timestamp-string))
         (funcall fdiff (current-time)))))
  
@@@ -17042,8 -17041,8 +17042,8 @@@ days in order to avoid rounding problem
          (match-end (match-end 0))
          (time1 (org-time-string-to-time ts1))
          (time2 (org-time-string-to-time ts2))
 -        (t1 (org-float-time time1))
 -        (t2 (org-float-time time2))
 +        (t1 (float-time time1))
 +        (t2 (float-time time2))
          (diff (abs (- t2 t1)))
          (negative (< (- t2 t1) 0))
          ;; (ys (floor (* 365 24 60 60)))
  
  (defun org-time-string-to-seconds (s)
    "Convert a timestamp string to a number of seconds."
 -  (org-float-time (org-time-string-to-time s)))
 +  (float-time (org-time-string-to-time s)))
  
  (defun org-time-string-to-absolute (s &optional daynr prefer show-all buffer pos)
    "Convert a time stamp to an absolute day number.
@@@ -17460,7 -17459,8 +17460,7 @@@ When SUPPRESS-TMP-DELAY is non-nil, sup
                         (+ (if (eq org-ts-what 'hour) n 0)   (nth 2 time0))
                         (+ (if (eq org-ts-what 'day) n 0)    (nth 3 time0))
                         (+ (if (eq org-ts-what 'month) n 0)  (nth 4 time0))
 -                       (+ (if (eq org-ts-what 'year) n 0)   (nth 5 time0))
 -                       (nthcdr 6 time0)))
 +                       (+ (if (eq org-ts-what 'year) n 0)   (nth 5 time0))))
        (when (and (member org-ts-what '(hour minute))
                 extra
                 (string-match "-\\([012][0-9]\\):\\([0-5][0-9]\\)" extra))
@@@ -22673,10 -22673,8 +22673,10 @@@ When optional argument END is non-nil, 
  time-range, if possible.
  
  The optional ZONE is omitted or nil for Emacs local time, t for
 -Universal Time, `wall' for system wall clock time, or a string as in
 -the TZ environment variable."
 +Universal Time, `wall' for system wall clock time, or a string as
 +in the TZ environment variable.  It can also be a list (as from
 +`current-time-zone') or an integer (as from `decode-time')
 +applied without consideration for daylight saving time."
    (format-time-string
     format
     (apply 'encode-time
diff --combined lisp/progmodes/python.el
index d4089a3ea922182dae8cb21811ddd4c9759444d3,49f7bcf5df9a2f3b18d15e4884a8001a130d0af8..ad69f8779e01a78072ab6898d88e4659d6b57876
@@@ -4,7 -4,7 +4,7 @@@
  
  ;; Author: Fabián E. Gallina <fgallina@gnu.org>
  ;; URL: https://github.com/fgallina/python.el
 -;; Version: 0.25.1
 +;; Version: 0.25.2
  ;; Package-Requires: ((emacs "24.1") (cl-lib "1.0"))
  ;; Maintainer: emacs-devel@gnu.org
  ;; Created: Jul 2010
    :version "24.3"
    :link '(emacs-commentary-link "python"))
  
 +
 +;;; 24.x Compat
 +\f
 +
 +(unless (fboundp 'prog-widen)
 +  (defun prog-widen ()
 +    (widen)))
 +
 +(unless (fboundp 'prog-first-column)
 +  (defun prog-first-column ()
 +    0))
 +
  \f
  ;;; Bindings
  
      ;; Some util commands
      (define-key map "\C-c\C-v" 'python-check)
      (define-key map "\C-c\C-f" 'python-eldoc-at-point)
 +    (define-key map "\C-c\C-d" 'python-describe-at-point)
      ;; Utilities
      (substitute-key-definition 'complete-symbol 'completion-at-point
                                 map global-map)
@@@ -562,32 -549,23 +562,32 @@@ The type returned can be `comment', `st
      ;; Builtin Exceptions
      (,(rx symbol-start
            (or
 +           ;; Python 2 and 3:
             "ArithmeticError" "AssertionError" "AttributeError" "BaseException"
 -           "DeprecationWarning" "EOFError" "EnvironmentError" "Exception"
 -           "FloatingPointError" "FutureWarning" "GeneratorExit" "IOError"
 -           "ImportError" "ImportWarning" "IndexError" "KeyError"
 -           "KeyboardInterrupt" "LookupError" "MemoryError" "NameError"
 -           "NotImplementedError" "OSError" "OverflowError"
 -           "PendingDeprecationWarning" "ReferenceError" "RuntimeError"
 -           "RuntimeWarning" "StopIteration" "SyntaxError" "SyntaxWarning"
 -           "SystemError" "SystemExit" "TypeError" "UnboundLocalError"
 -           "UnicodeDecodeError" "UnicodeEncodeError" "UnicodeError"
 -           "UnicodeTranslateError" "UnicodeWarning" "UserWarning" "VMSError"
 -           "ValueError" "Warning" "WindowsError" "ZeroDivisionError"
 +           "BufferError" "BytesWarning" "DeprecationWarning" "EOFError"
 +           "EnvironmentError" "Exception" "FloatingPointError" "FutureWarning"
 +           "GeneratorExit" "IOError" "ImportError" "ImportWarning"
 +           "IndentationError" "IndexError" "KeyError" "KeyboardInterrupt"
 +           "LookupError" "MemoryError" "NameError" "NotImplementedError"
 +           "OSError" "OverflowError" "PendingDeprecationWarning"
 +           "ReferenceError" "RuntimeError" "RuntimeWarning" "StopIteration"
 +           "SyntaxError" "SyntaxWarning" "SystemError" "SystemExit" "TabError"
 +           "TypeError" "UnboundLocalError" "UnicodeDecodeError"
 +           "UnicodeEncodeError" "UnicodeError" "UnicodeTranslateError"
 +           "UnicodeWarning" "UserWarning" "ValueError" "Warning"
 +           "ZeroDivisionError"
             ;; Python 2:
             "StandardError"
             ;; Python 3:
 -           "BufferError" "BytesWarning" "IndentationError" "ResourceWarning"
 -           "TabError")
 +           "BlockingIOError" "BrokenPipeError" "ChildProcessError"
 +           "ConnectionAbortedError" "ConnectionError" "ConnectionRefusedError"
 +           "ConnectionResetError" "FileExistsError" "FileNotFoundError"
 +           "InterruptedError" "IsADirectoryError" "NotADirectoryError"
 +           "PermissionError" "ProcessLookupError" "RecursionError"
 +           "ResourceWarning" "StopAsyncIteration" "TimeoutError"
 +           ;; OS specific
 +           "VMSError" "WindowsError"
 +           )
            symbol-end) . font-lock-type-face)
      ;; Builtins
      (,(rx symbol-start
@@@ -781,7 -759,7 +781,7 @@@ work on `python-indent-calculate-indent
    (interactive)
    (save-excursion
      (save-restriction
 -      (widen)
 +      (prog-widen)
        (goto-char (point-min))
        (let ((block-end))
          (while (and (not block-end)
@@@ -880,7 -858,7 +880,7 @@@ keywor
   - Point is on a line starting a dedenter block.
   - START is the position where the dedenter block starts."
    (save-restriction
 -    (widen)
 +    (prog-widen)
      (let ((ppss (save-excursion
                    (beginning-of-line)
                    (syntax-ppss))))
@@@ -1027,10 -1005,10 +1027,10 @@@ current context or a list of integers
  happening for :at-dedenter-block-start context since the
  possibilities can be narrowed to specific indentation points."
    (save-restriction
 -    (widen)
 +    (prog-widen)
      (save-excursion
        (pcase (python-indent-context)
 -        (`(:no-indent . ,_) 0)
 +        (`(:no-indent . ,_) (prog-first-column)) ; usually 0
          (`(,(or :after-line
                  :after-comment
                  :inside-string
           (let ((opening-block-start-points
                  (python-info-dedenter-opening-block-positions)))
             (if (not opening-block-start-points)
 -                ; if not found default to first column
 +               (prog-first-column) ; if not found default to first column
               (mapcar (lambda (pos)
                         (save-excursion
                           (goto-char pos)
@@@ -1086,7 -1064,7 +1086,7 @@@ integers.  Levels are returned in ascen
  case INDENTATION is a list, this order is enforced."
    (if (listp indentation)
        (sort (copy-sequence indentation) #'<)
 -    (nconc (number-sequence 0 (1- indentation)
 +    (nconc (number-sequence (prog-first-column) (1- indentation)
                              python-indent-offset)
             (list indentation))))
  
@@@ -1111,7 -1089,7 +1111,7 @@@ minimum.
          (python-indent--previous-level levels (current-indentation))
        (if levels
            (apply #'max levels)
 -        0))))
 +        (prog-first-column)))))
  
  (defun python-indent-line (&optional previous)
    "Internal implementation of `python-indent-line-function'.
@@@ -2064,8 -2042,8 +2064,8 @@@ virtualenv.
  (defun python-shell-calculate-pythonpath ()
    "Calculate the PYTHONPATH using `python-shell-extra-pythonpaths'."
    (let ((pythonpath
 -         (tramp-compat-split-string
 -          (or (getenv "PYTHONPATH") "") path-separator)))
 +         (split-string
 +          (or (getenv "PYTHONPATH") "") path-separator 'omit)))
      (python-shell--add-to-path-with-priority
       pythonpath python-shell-extra-pythonpaths)
      (mapconcat 'identity pythonpath path-separator)))
@@@ -2136,7 -2114,7 +2136,7 @@@ appends `python-shell-remote-exec-path
             (md5 tramp-end-of-output)))
        unset vars item)
      (while env
 -      (setq item (tramp-compat-split-string (car env) "="))
 +      (setq item (split-string (car env) "=" 'omit))
        (setcdr item (mapconcat 'identity (cdr item) "="))
        (if (and (stringp (cdr item)) (not (string-equal (cdr item) "")))
          (push (format "%s %s" (car item) (cdr item)) vars)
@@@ -2700,6 -2678,7 +2700,7 @@@ variable
  \(Type \\[describe-mode] in the process buffer for a list of commands.)"
    (when python-shell--parent-buffer
      (python-util-clone-local-variables python-shell--parent-buffer))
+   (set (make-local-variable 'indent-tabs-mode) nil)
    ;; Users can interactively override default values for
    ;; `python-shell-interpreter' and `python-shell-interpreter-args'
    ;; when calling `run-python'.  This ensures values let-bound in
@@@ -4045,8 -4024,8 +4046,8 @@@ The skeleton will be bound to python-sk
    (declare (indent 2))
    (let* ((name (symbol-name name))
           (function-name (intern (concat "python-skeleton--" name)))
 -         (msg (format-message
 -               "Add `%s' clause? " name)))
 +         (msg (funcall (if (fboundp 'format-message) #'format-message #'format)
 +                       "Add `%s' clause? " name)))
      (when (not skel)
        (setq skel
              `(< ,(format "%s:" name) \n \n
@@@ -4313,12 -4292,47 +4314,47 @@@ returns will be used.  If not FORCE-PRO
          (unless (zerop (length docstring))
            docstring)))))
  
+ (defvar-local python-eldoc-get-doc t
+   "Non-nil means eldoc should fetch the documentation
+   automatically. Set to nil by `python-eldoc-function' if
+   `python-eldoc-function-timeout-permanent' is non-nil and
+   `python-eldoc-function' times out.")
+ (defcustom python-eldoc-function-timeout 1
+   "Timeout for `python-eldoc-function' in seconds."
+   :group 'python
+   :type 'integer
+   :version "25.1")
+ (defcustom python-eldoc-function-timeout-permanent t
+   "Non-nil means that when `python-eldoc-function' times out
+ `python-eldoc-get-doc' will be set to nil"
+   :group 'python
+   :type 'boolean
+   :version "25.1")
  (defun python-eldoc-function ()
    "`eldoc-documentation-function' for Python.
  For this to work as best as possible you should call
  `python-shell-send-buffer' from time to time so context in
- inferior Python process is updated properly."
-   (python-eldoc--get-doc-at-point))
+ inferior Python process is updated properly.
+ If `python-eldoc-function-timeout' seconds elapse before this
+ function returns then if
+ `python-eldoc-function-timeout-permanent' is non-nil
+ `python-eldoc-get-doc' will be set to nil and eldoc will no
+ longer return the documentation at the point automatically.
+ Set `python-eldoc-get-doc' to t to reenable eldoc documentation
+ fetching"
+   (when python-eldoc-get-doc
+     (with-timeout (python-eldoc-function-timeout
+                    (if python-eldoc-function-timeout-permanent
+                        (progn
+                          (message "Eldoc echo-area display muted in this buffer, see `python-eldoc-function'")
+                          (setq python-eldoc-get-doc nil))
+                      (message "`python-eldoc-function' timed out, see `python-eldoc-function-timeout'")))
+       (python-eldoc--get-doc-at-point))))
  
  (defun python-eldoc-at-point (symbol)
    "Get help on SYMBOL using `help'.
@@@ -4332,11 -4346,6 +4368,11 @@@ Interactively, prompt for symbol.
                          nil nil symbol))))
    (message (python-eldoc--get-doc-at-point symbol)))
  
 +(defun python-describe-at-point (symbol process)
 +  (interactive (list (python-info-current-symbol)
 +                     (python-shell-get-process)))
 +  (comint-send-string process (concat "help('" symbol "')\n")))
 +
  \f
  ;;; Hideshow
  
@@@ -4504,7 -4513,7 +4540,7 @@@ Optional argument INCLUDE-TYPE indicate
  This function can be used as the value of `add-log-current-defun-function'
  since it returns nil if point is not inside a defun."
    (save-restriction
 -    (widen)
 +    (prog-widen)
      (save-excursion
        (end-of-line 1)
        (let ((names)
@@@ -4687,7 -4696,7 +4723,7 @@@ likely an invalid python file.
    (let ((point (python-info-dedenter-opening-block-position)))
      (when point
        (save-restriction
 -        (widen)
 +        (prog-widen)
          (message "Closes %s" (save-excursion
                                 (goto-char point)
                                 (buffer-substring
@@@ -4708,7 -4717,7 +4744,7 @@@ statement.
  With optional argument LINE-NUMBER, check that line instead."
    (save-excursion
      (save-restriction
 -      (widen)
 +      (prog-widen)
        (when line-number
          (python-util-goto-line line-number))
        (while (and (not (eobp))
  Optional argument LINE-NUMBER forces the line number to check against."
    (save-excursion
      (save-restriction
 -      (widen)
 +      (prog-widen)
        (when line-number
          (python-util-goto-line line-number))
        (when (python-info-line-ends-backslash-p)
@@@ -4741,7 -4750,7 +4777,7 @@@ When current line is continuation of an
  where the continued line ends."
    (save-excursion
      (save-restriction
 -      (widen)
 +      (prog-widen)
        (let* ((context-type (progn
                               (back-to-indentation)
                               (python-syntax-context-type)))
diff --combined lisp/simple.el
index 6c309293bd4a906c4fbff2ce613b5be985dea8b0,e38bf70f520cd3262d559ff2ded0adff0bec148c..10b4f392d50a22b43c706c106483ea3d3a22c337
@@@ -1075,9 -1075,7 +1075,9 @@@ that uses or sets the mark.
    (interactive)
    (push-mark (point))
    (push-mark (point-max) nil t)
 -  (goto-char (point-min)))
 +  ;; This is really `point-min' in most cases, but if we're in the
 +  ;; minibuffer, this is at the end of the prompt.
 +  (goto-char (minibuffer-prompt-end)))
  \f
  
  ;; Counting lines, one way or another.
@@@ -1635,12 -1633,6 +1635,12 @@@ If the value is non-nil and not a numbe
                   (integer :tag "time" 2)
                   (other :tag "on")))
  
 +(defcustom extended-command-suggest-shorter t
 +  "If non-nil, show a shorter M-x invocation when there is one."
 +  :group 'keyboard
 +  :type 'boolean
 +  :version "25.2")
 +
  (defun execute-extended-command--shorter-1 (name length)
    (cond
     ((zerop length) (list ""))
@@@ -1723,8 -1715,7 +1723,8 @@@ invoking, give a prefix argument to `ex
                          ((numberp suggest-key-bindings) suggest-key-bindings)
                          (t 2))))))
        (when (and waited (not (consp unread-command-events)))
 -        (unless (or binding executing-kbd-macro (not (symbolp function))
 +        (unless (or (not extended-command-suggest-shorter)
 +                    binding executing-kbd-macro (not (symbolp function))
                      (<= (length (symbol-name function)) 2))
            ;; There's no binding for CMD.  Let's try and find the shortest
            ;; string to use in M-x.
@@@ -2919,9 -2910,7 +2919,7 @@@ REASON describes the reason that the bo
  
  This list is maintained by `undo-auto--undoable-change' and
  `undo-auto--boundaries' and can be affected by changes to their
- default values.
- See also `undo-auto--buffer-undoably-changed'.")
+ default values.")
  
  (defun undo-auto--add-boundary ()
    "Add an `undo-boundary' in appropriate buffers."
@@@ -3765,7 -3754,6 +3763,7 @@@ support pty association, if PROGRAM is 
  (define-derived-mode process-menu-mode tabulated-list-mode "Process Menu"
    "Major mode for listing the processes called by Emacs."
    (setq tabulated-list-format [("Process" 15 t)
 +                             ("PID"      7 t)
                               ("Status"   7 t)
                               ("Buffer"  15 t)
                               ("TTY"     12 t)
  (defun process-menu-delete-process ()
    "Kill process at point in a `list-processes' buffer."
    (interactive)
 -  (delete-process (tabulated-list-get-id))
 -  (revert-buffer))
 +  (let ((pos (point)))
 +    (delete-process (tabulated-list-get-id))
 +    (revert-buffer)
 +    (goto-char (min pos (point-max)))
 +    (if (eobp)
 +        (forward-line -1)
 +      (beginning-of-line))))
  
  (defun list-processes--refresh ()
    "Recompute the list of processes for the Process List buffer.
@@@ -3797,7 -3780,6 +3795,7 @@@ Also, delete any process that is exite
               (process-query-on-exit-flag p))
           (let* ((buf (process-buffer p))
                  (type (process-type p))
 +                (pid  (if (process-id p) (format "%d" (process-id p)) "--"))
                  (name (process-name p))
                  (status (symbol-name (process-status p)))
                  (buf-label (if (buffer-live-p buf)
                                         (format " at %s b/s" speed)
                                       "")))))
                     (mapconcat 'identity (process-command p) " "))))
 -           (push (list p (vector name status buf-label tty cmd))
 +           (push (list p (vector name pid status buf-label tty cmd))
                   tabulated-list-entries))))))
  
  (defun process-menu-visit-buffer (button)
@@@ -4076,8 -4058,7 +4074,8 @@@ Its arguments and return value are as s
  This respects the wrapper hook `filter-buffer-substring-functions',
  and the abnormal hook `buffer-substring-filters'.
  No filtering is done unless a hook says to."
 -  (with-wrapper-hook filter-buffer-substring-functions (beg end delete)
 +  (subr--with-wrapper-hook-no-warnings
 +    filter-buffer-substring-functions (beg end delete)
      (cond
       ((or delete buffer-substring-filters)
        (save-excursion
@@@ -5853,7 -5834,7 +5851,7 @@@ The value is a floating-point number.
      (/ (float (- (nth 3 edges) (nth 1 edges))) dlh)))
  
  ;; Returns non-nil if partial move was done.
 -(defun line-move-partial (arg noerror to-end)
 +(defun line-move-partial (arg noerror &optional _to-end)
    (if (< arg 0)
        ;; Move backward (up).
        ;; If already vscrolled, reduce vscroll
          ;; discrepancies between that and DLH.
          (if (and rowh rbot (>= (- (+ rowh rbot) winh) 1))
              (set-window-vscroll nil dlh t))
 -        (line-move-1 arg noerror to-end)
 +        (line-move-1 arg noerror)
          t)
         ;; If there are lines above the last line, scroll-up one line.
         ((and vpos (> vpos 0))
  ;; scrolling with cursor motion.  But so far we don't have
  ;; a cleaner solution to the problem of making C-n do something
  ;; useful given a tall image.
 -(defun line-move (arg &optional noerror to-end try-vscroll)
 +(defun line-move (arg &optional noerror _to-end try-vscroll)
    "Move forward ARG lines.
  If NOERROR, don't signal an error if we can't move ARG lines.
  TO-END is unused.
@@@ -5976,7 -5957,7 +5974,7 @@@ TRY-VSCROLL controls whether to vscrol
  `auto-window-vscroll' or TRY-VSCROLL is nil, this function will
  not vscroll."
    (if noninteractive
 -      (line-move-1 arg noerror to-end)
 +      (line-move-1 arg noerror)
      (unless (and auto-window-vscroll try-vscroll
                 ;; Only vscroll for single line moves
                 (= (abs arg) 1)
                 ;; But don't vscroll in a keyboard macro.
                 (not defining-kbd-macro)
                 (not executing-kbd-macro)
 -               (line-move-partial arg noerror to-end))
 +               (line-move-partial arg noerror))
        (set-window-vscroll nil 0 t)
        (if (and line-move-visual
               ;; Display-based column are incompatible with goal-column.
                  (set-window-vscroll
                   nil
                   (- lh dlh) t))))
 -      (line-move-1 arg noerror to-end)))))
 +      (line-move-1 arg noerror)))))
  
  ;; Display-based alternative to line-move-1.
  ;; Arg says how many lines to move.  The value is t if we can move the
@@@ -6056,13 -6037,7 +6054,13 @@@ If NOERROR, don't signal an error if w
          (setq temporary-goal-column
                (cons (/ (float x-pos)
                         (frame-char-width))
 -                      hscroll))))))
 +                      hscroll)))
 +       (executing-kbd-macro
 +        ;; When we move beyond the first/last character visible in
 +        ;; the window, posn-at-point will return nil, so we need to
 +        ;; approximate the goal column as below.
 +        (setq temporary-goal-column
 +              (mod (current-column) (window-text-width)))))))
      (if target-hscroll
        (set-window-hscroll (selected-window) target-hscroll))
      ;; vertical-motion can move more than it was asked to if it moves
diff --combined lisp/subr.el
index 358bfa5e1c00ca93b06c4793476afa327c20701c,ed2166a0ee29f11ed6709de05df0ec399cfbb5d0..48ff5013ceea3c2b3a8d799088d0b8beaeac9d8d
  ;; 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:
 -
 -;;; Code:
 -
  ;; Beware: while this file has tag `utf-8', before it's compiled, it gets
  ;; loaded as "raw-text", so non-ASCII chars won't work right during bootstrap.
  
 -(defmacro declare-function (_fn _file &optional _arglist _fileonly)
 +
 +;; declare-function's args use &rest, not &optional, for compatibility
 +;; with byte-compile-macroexpand-declare-function.
 +
 +(defmacro declare-function (_fn _file &rest _args)
    "Tell the byte-compiler that function FN is defined, in FILE.
 -Optional ARGLIST is the argument list used by the function.
  The FILE argument is not used by the byte-compiler, but by the
  `check-declare' package, which checks that FILE contains a
 -definition for FN.  ARGLIST is used by both the byte-compiler
 -and `check-declare' to check for consistency.
 +definition for FN.
  
  FILE can be either a Lisp file (in which case the \".el\"
  extension is optional), or a C file.  C files are expanded
@@@ -44,22 -46,19 +44,22 @@@ declaration.  A FILE with an \"ext:\" p
  `check-declare' will check such files if they are found, and skip
  them without error if they are not.
  
 -FILEONLY non-nil means that `check-declare' will only check that
 -FILE exists, not that it defines FN.  This is intended for
 -function-definitions that `check-declare' does not recognize, e.g.
 -`defstruct'.
 +Optional ARGLIST specifies FN's arguments, or is t to not specify
 +FN's arguments.  An omitted ARGLIST defaults to t, not nil: a nil
 +ARGLIST specifies an empty argument list, and an explicit t
 +ARGLIST is a placeholder that allows supplying a later arg.
  
 -To specify a value for FILEONLY without passing an argument list,
 -set ARGLIST to t.  This is necessary because nil means an
 -empty argument list, rather than an unspecified one.
 +Optional FILEONLY non-nil means that `check-declare' will check
 +only that FILE exists, not that it defines FN.  This is intended
 +for function definitions that `check-declare' does not recognize,
 +e.g., `defstruct'.
  
  Note that for the purposes of `check-declare', this statement
  must be the first non-whitespace on a line.
  
  For more information, see Info node `(elisp)Declaring Functions'."
 +  (declare (advertised-calling-convention
 +          (fn file &optional arglist fileonly) nil))
    ;; Does nothing - byte-compile-declare-function does the work.
    nil)
  
@@@ -67,7 -66,6 +67,7 @@@
  ;;;; Basic Lisp macros.
  
  (defalias 'not 'null)
 +(defalias 'sxhash 'sxhash-equal)
  
  (defmacro noreturn (form)
    "Evaluate FORM, expecting it not to return.
@@@ -600,10 -598,12 +600,12 @@@ Elements of ALIST that are not conses a
    alist)
  
  (defun alist-get (key alist &optional default remove)
-   "Get the value associated to KEY in ALIST.
- DEFAULT is the value to return if KEY is not found in ALIST.
- REMOVE, if non-nil, means that when setting this element, we should
- remove the entry if the new value is `eql' to DEFAULT."
+   "Return the value associated with KEY in ALIST, using `assq'.
+ If KEY is not found in ALIST, return DEFAULT.
+ This is a generalized variable suitable for use with `setf'.
+ When using it to set a value, optional argument REMOVE non-nil
+ means to remove KEY from ALIST if the new value is `eql' to DEFAULT."
    (ignore remove) ;;Silence byte-compiler.
    (let ((x (assq key alist)))
      (if x (cdr x) default)))
@@@ -859,12 -859,7 +861,12 @@@ above 127 (such as ISO Latin-1) can be 
  Note that if KEY has a local binding in the current buffer,
  that local binding will continue to shadow any global binding
  that you make with this function."
 -  (interactive "KSet key globally: \nCSet key %s to command: ")
 +  (interactive
 +   (let* ((menu-prompting nil)
 +          (key (read-key-sequence "Set key globally: ")))
 +     (list key
 +           (read-command (format "Set key %s to command: "
 +                                 (key-description key))))))
    (or (vectorp key) (stringp key)
        (signal 'wrong-type-argument (list 'arrayp key)))
    (define-key (current-global-map) key command))
@@@ -1550,10 -1545,6 +1552,10 @@@ FUN is then called once.
    (declare (indent 2) (debug (form sexp body))
             (obsolete "use a <foo>-function variable modified by `add-function'."
                       "24.4"))
 +  `(subr--with-wrapper-hook-no-warnings ,hook ,args ,@body))
 +
 +(defmacro subr--with-wrapper-hook-no-warnings (hook args &rest body)
 +  "Like (with-wrapper-hook HOOK ARGS BODY), but without warnings."
    ;; We need those two gensyms because CL's lexical scoping is not available
    ;; for function arguments :-(
    (let ((funs (make-symbol "funs"))
@@@ -1744,11 -1735,6 +1746,11 @@@ if it is empty or a duplicate.
  (make-variable-buffer-local 'delayed-mode-hooks)
  (put 'delay-mode-hooks 'permanent-local t)
  
 +(defvar delayed-after-hook-forms nil
 +  "List of delayed :after-hook forms waiting to be run.
 +These forms come from `define-derived-mode'.")
 +(make-variable-buffer-local 'delayed-after-hook-forms)
 +
  (defvar change-major-mode-after-body-hook nil
    "Normal hook run in major mode functions, before the mode hooks.")
  
  
  (defun run-mode-hooks (&rest hooks)
    "Run mode hooks `delayed-mode-hooks' and HOOKS, or delay HOOKS.
 -If the variable `delay-mode-hooks' is non-nil, does not run any hooks,
 +Call `hack-local-variables' to set up file local and directory local
 +variables.
 +
 +If the variable `delay-mode-hooks' is non-nil, does not do anything,
  just adds the HOOKS to the list `delayed-mode-hooks'.
  Otherwise, runs hooks in the sequence: `change-major-mode-after-body-hook',
 -`delayed-mode-hooks' (in reverse order), HOOKS, and finally
 -`after-change-major-mode-hook'.  Major mode functions should use
 -this instead of `run-hooks' when running their FOO-mode-hook."
 +`delayed-mode-hooks' (in reverse order), HOOKS, then runs
 +`hack-local-variables', runs the hook `after-change-major-mode-hook', and
 +finally evaluates the forms in `delayed-after-hook-forms' (see
 +`define-derived-mode').
 +
 +Major mode functions should use this instead of `run-hooks' when
 +running their FOO-mode-hook."
    (if delay-mode-hooks
        ;; Delaying case.
        (dolist (hook hooks)
      (setq hooks (nconc (nreverse delayed-mode-hooks) hooks))
      (setq delayed-mode-hooks nil)
      (apply 'run-hooks (cons 'change-major-mode-after-body-hook hooks))
 -    (run-hooks 'after-change-major-mode-hook)))
 +    (if (buffer-file-name)
 +        (with-demoted-errors "File local-variables error: %s"
 +          (hack-local-variables 'no-mode)))
 +    (run-hooks 'after-change-major-mode-hook)
 +    (dolist (form (nreverse delayed-after-hook-forms))
 +      (eval form))
 +    (setq delayed-after-hook-forms nil)))
  
  (defmacro delay-mode-hooks (&rest body)
    "Execute BODY, but delay any `run-mode-hooks'.
@@@ -2280,171 -2253,6 +2282,171 @@@ keyboard-quit events while waiting for 
      (message "%s%s" prompt (char-to-string char))
      char))
  
 +(defun read-multiple-choice (prompt choices)
 +  "Ask user a multiple choice question.
 +PROMPT should be a string that will be displayed as the prompt.
 +
 +CHOICES is an alist where the first element in each entry is a
 +character to be entered, the second element is a short name for
 +the entry to be displayed while prompting (if there's room, it
 +might be shortened), and the third, optional entry is a longer
 +explanation that will be displayed in a help buffer if the user
 +requests more help.
 +
 +This function translates user input into responses by consulting
 +the bindings in `query-replace-map'; see the documentation of
 +that variable for more information.  In this case, the useful
 +bindings are `recenter', `scroll-up', and `scroll-down'.  If the
 +user enters `recenter', `scroll-up', or `scroll-down' responses,
 +perform the requested window recentering or scrolling and ask
 +again.
 +
 +The return value is the matching entry from the CHOICES list.
 +
 +Usage example:
 +
 +\(read-multiple-choice \"Continue connecting?\"
 +                      '((?a \"always\")
 +                        (?s \"session only\")
 +                        (?n \"no\")))"
 +  (let* ((altered-names nil)
 +         (full-prompt
 +          (format
 +           "%s (%s): "
 +           prompt
 +           (mapconcat
 +            (lambda (elem)
 +              (let* ((name (cadr elem))
 +                     (pos (seq-position name (car elem)))
 +                     (altered-name
 +                      (cond
 +                       ;; Not in the name string.
 +                       ((not pos)
 +                        (format "[%c] %s" (car elem) name))
 +                       ;; The prompt character is in the name, so highlight
 +                       ;; it on graphical terminals...
 +                       ((display-supports-face-attributes-p
 +                         '(:underline t) (window-frame))
 +                        (setq name (copy-sequence name))
 +                        (put-text-property pos (1+ pos)
 +                                           'face 'read-multiple-choice-face
 +                                           name)
 +                        name)
 +                       ;; And put it in [bracket] on non-graphical terminals.
 +                       (t
 +                        (concat
 +                         (substring name 0 pos)
 +                         "["
 +                         (upcase (substring name pos (1+ pos)))
 +                         "]"
 +                         (substring name (1+ pos)))))))
 +                (push (cons (car elem) altered-name)
 +                      altered-names)
 +                altered-name))
 +            (append choices '((?? "?")))
 +            ", ")))
 +         tchar buf wrong-char answer)
 +    (save-window-excursion
 +      (save-excursion
 +      (while (not tchar)
 +        (message "%s%s"
 +                   (if wrong-char
 +                       "Invalid choice.  "
 +                     "")
 +                   full-prompt)
 +          (setq tchar
 +                (if (and (display-popup-menus-p)
 +                         last-input-event ; not during startup
 +                         (listp last-nonmenu-event)
 +                         use-dialog-box)
 +                    (x-popup-dialog
 +                     t
 +                     (cons prompt
 +                           (mapcar
 +                            (lambda (elem)
 +                              (cons (capitalize (cadr elem))
 +                                    (car elem)))
 +                            choices)))
 +                  (condition-case nil
 +                      (let ((cursor-in-echo-area t))
 +                        (read-char))
 +                    (error nil))))
 +          (setq answer (lookup-key query-replace-map (vector tchar) t))
 +          (setq tchar
 +                (cond
 +                 ((eq answer 'recenter)
 +                  (recenter) t)
 +                 ((eq answer 'scroll-up)
 +                  (ignore-errors (scroll-up-command)) t)
 +                 ((eq answer 'scroll-down)
 +                  (ignore-errors (scroll-down-command)) t)
 +                 ((eq answer 'scroll-other-window)
 +                  (ignore-errors (scroll-other-window)) t)
 +                 ((eq answer 'scroll-other-window-down)
 +                  (ignore-errors (scroll-other-window-down)) t)
 +                 (t tchar)))
 +          (when (eq tchar t)
 +            (setq wrong-char nil
 +                  tchar nil))
 +          ;; The user has entered an invalid choice, so display the
 +          ;; help messages.
 +          (when (and (not (eq tchar nil))
 +                     (not (assq tchar choices)))
 +          (setq wrong-char (not (memq tchar '(?? ?\C-h)))
 +                  tchar nil)
 +            (when wrong-char
 +              (ding))
 +            (with-help-window (setq buf (get-buffer-create
 +                                         "*Multiple Choice Help*"))
 +              (with-current-buffer buf
 +                (erase-buffer)
 +                (pop-to-buffer buf)
 +                (insert prompt "\n\n")
 +                (let* ((columns (/ (window-width) 25))
 +                       (fill-column 21)
 +                       (times 0)
 +                       (start (point)))
 +                  (dolist (elem choices)
 +                    (goto-char start)
 +                    (unless (zerop times)
 +                      (if (zerop (mod times columns))
 +                          ;; Go to the next "line".
 +                          (goto-char (setq start (point-max)))
 +                        ;; Add padding.
 +                        (while (not (eobp))
 +                          (end-of-line)
 +                          (insert (make-string (max (- (* (mod times columns)
 +                                                          (+ fill-column 4))
 +                                                       (current-column))
 +                                                    0)
 +                                               ?\s))
 +                          (forward-line 1))))
 +                    (setq times (1+ times))
 +                    (let ((text
 +                           (with-temp-buffer
 +                             (insert (format
 +                                      "%c: %s\n"
 +                                      (car elem)
 +                                      (cdr (assq (car elem) altered-names))))
 +                             (fill-region (point-min) (point-max))
 +                             (when (nth 2 elem)
 +                               (let ((start (point)))
 +                                 (insert (nth 2 elem))
 +                                 (unless (bolp)
 +                                   (insert "\n"))
 +                                 (fill-region start (point-max))))
 +                             (buffer-string))))
 +                      (goto-char start)
 +                      (dolist (line (split-string text "\n"))
 +                        (end-of-line)
 +                        (if (bolp)
 +                            (insert line "\n")
 +                          (insert line))
 +                        (forward-line 1)))))))))))
 +    (when (buffer-live-p buf)
 +      (kill-buffer buf))
 +    (assq tchar choices)))
 +
  (defun sit-for (seconds &optional nodisp obsolete)
    "Redisplay, then wait for SECONDS seconds.  Stop when input is available.
  SECONDS may be a floating-point value.
@@@ -4328,7 -4136,8 +4330,7 @@@ and the function returns nil.  Field bo
  `inhibit-field-text-motion' is non-nil.
  
  This function is like `forward-word', but it is not affected
 -by `find-word-boundary-function-table' (as set up by
 -e.g. `subword-mode').  It is also not interactive."
 +by `find-word-boundary-function-table'.  It is also not interactive."
    (let ((find-word-boundary-function-table
           (if (char-table-p word-move-empty-char-table)
               word-move-empty-char-table
@@@ -4341,7 -4150,8 +4343,7 @@@ With argument ARG, do this that many ti
  If ARG is omitted or nil, move point backward one word.
  
  This function is like `forward-word', but it is not affected
 -by `find-word-boundary-function-table' (as set up by
 -e.g. `subword-mode').  It is also not interactive."
 +by `find-word-boundary-function-table'.  It is also not interactive."
    (let ((find-word-boundary-function-table
           (if (char-table-p word-move-empty-char-table)
               word-move-empty-char-table
@@@ -5154,26 -4964,6 +5156,26 @@@ as a list."
  
  \f
  ;;; Misc.
 +
 +(defvar definition-prefixes (make-hash-table :test 'equal)
 +  "Hash table mapping prefixes to the files in which they're used.
 +This can be used to automatically fetch not-yet-loaded definitions.
 +More specifically, if there is a value of the form (FILES...) for a string PREFIX
 +it means that the FILES define variables or functions with names that start
 +with PREFIX.
 +
 +Note that it does not imply that all definitions starting with PREFIX can
 +be found in those files.  E.g. if prefix is \"gnus-article-\" there might
 +still be definitions of the form \"gnus-article-toto-titi\" in other files, which would
 +presumably appear in this table under another prefix such as \"gnus-\"
 +or \"gnus-article-toto-\".")
 +
 +(defun register-definition-prefixes (file prefixes)
 +  "Register that FILE uses PREFIXES."
 +  (dolist (prefix prefixes)
 +    (puthash prefix (cons file (gethash prefix definition-prefixes))
 +             definition-prefixes)))
 +
  (defconst menu-bar-separator '("--")
    "Separator for menus.")
  
diff --combined src/keyboard.c
index 717c0710a5c5a151f9e64b2540009f4e1bae0e58,2db9aaf0297e894ce88772e51960144de8259e49..653f52732a70dacc634049bf44f566764c8c418f
@@@ -681,6 -681,14 +681,14 @@@ recursive_edit_1 (void
    specbind (Qinhibit_redisplay, Qnil);
    redisplaying_p = 0;
  
+   /* This variable stores buffers that have changed so that an undo
+      boundary can be added. specbind this so that changes in the
+      recursive edit will not result in undo boundaries in buffers
+      changed before we entered there recursive edit.
+      See Bug #23632.
+   */
+   specbind (Qundo_auto__undoably_changed_buffers, Qnil);
    val = command_loop ();
    if (EQ (val, Qt))
      Fsignal (Qquit, Qnil);
@@@ -2122,7 -2130,7 +2130,7 @@@ read_event_from_main_queue (struct time
  {
    Lisp_Object c = Qnil;
    sys_jmp_buf save_jump;
 -  KBOARD *kb IF_LINT (= NULL);
 +  KBOARD *kb;
  
   start:
  
@@@ -2193,8 -2201,8 +2201,8 @@@ read_decoded_event_from_main_queue (str
                                      Lisp_Object prev_event,
                                      bool *used_mouse_menu)
  {
 -#define MAX_ENCODED_BYTES 16
  #ifndef WINDOWSNT
 +#define MAX_ENCODED_BYTES 16
    Lisp_Object events[MAX_ENCODED_BYTES];
    int n = 0;
  #endif
@@@ -2312,7 -2320,7 +2320,7 @@@ read_char (int commandflag, Lisp_Objec
           Lisp_Object prev_event,
           bool *used_mouse_menu, struct timespec *end_time)
  {
 -  Lisp_Object c;
 +  Lisp_Object NONVOLATILE c;
    ptrdiff_t jmpcount;
    sys_jmp_buf local_getcjmp;
    sys_jmp_buf save_jump;
        last_input_event = c;
        call4 (Qcommand_execute, tem, Qnil, Fvector (1, &last_input_event), Qt);
  
 -      if (CONSP (c) && EQ (XCAR (c), Qselect_window) && !end_time)
 +      if (CONSP (c)
 +          && (EQ (XCAR (c), Qselect_window)
 +#ifdef HAVE_DBUS
 +            || EQ (XCAR (c), Qdbus_event)
 +#endif
 +#ifdef USE_FILE_NOTIFY
 +            || EQ (XCAR (c), Qfile_notify)
 +#endif
 +            || EQ (XCAR (c), Qconfig_changed_event))
 +          && !end_time)
        /* We stopped being idle for this event; undo that.  This
           prevents automatic window selection (under
           mouse-autoselect-window) from acting as a real input event, for
@@@ -3893,16 -3892,6 +3901,16 @@@ kbd_buffer_get_event (KBOARD **kbp
          kbd_fetch_ptr = event + 1;
        }
  #endif
 +
 +#ifdef HAVE_NTGUI
 +      else if (event->kind == END_SESSION_EVENT)
 +      {
 +        /* Make an event (end-session).  */
 +        obj = list1 (Qend_session);
 +        kbd_fetch_ptr = event + 1;
 +      }
 +#endif
 +
  #if defined (HAVE_X11) || defined (HAVE_NTGUI) \
      || defined (HAVE_NS)
        else if (event->kind == ICONIFY_EVENT)
@@@ -5990,6 -5979,7 +5998,6 @@@ make_lispy_event (struct input_event *e
        }
  #endif
  
 -
  #if defined HAVE_INOTIFY || defined HAVE_KQUEUE || defined HAVE_GFILENOTIFY
      case FILE_NOTIFY_EVENT:
        {
@@@ -6889,10 -6879,7 +6897,10 @@@ tty_read_avail_input (struct terminal *
       the kbd_buffer can really hold.  That may prevent loss
       of characters on some systems when input is stuffed at us.  */
    unsigned char cbuf[KBD_BUFFER_SIZE - 1];
 -  int n_to_read, i;
 +#ifndef WINDOWSNT
 +  int n_to_read;
 +#endif
 +  int i;
    struct tty_display_info *tty = terminal->display_info.tty;
    int nread = 0;
  #ifdef subprocesses
@@@ -8841,7 -8828,7 +8849,7 @@@ read_key_sequence (Lisp_Object *keybuf
  
    /* The length of the echo buffer when we started reading, and
       the length of this_command_keys when we started reading.  */
 -  ptrdiff_t echo_start IF_LINT (= 0);
 +  ptrdiff_t echo_start UNINIT;
    ptrdiff_t keys_start;
  
    Lisp_Object current_binding = Qnil;
       While we're reading, we keep the event here.  */
    Lisp_Object delayed_switch_frame;
  
 -  Lisp_Object original_uppercase IF_LINT (= Qnil);
 +  Lisp_Object original_uppercase UNINIT;
    int original_uppercase_position = -1;
  
    /* Gets around Microsoft compiler limitations.  */
         while those allow us to restart the entire key sequence,
         echo_local_start and keys_local_start allow us to throw away
         just one key.  */
 -      ptrdiff_t echo_local_start IF_LINT (= 0);
 +      ptrdiff_t echo_local_start UNINIT;
        int keys_local_start;
        Lisp_Object new_binding;
  
@@@ -10330,9 -10317,6 +10338,9 @@@ handle_interrupt (bool in_signal_handle
         is used.  Note that [Enter] is not echoed by dos.  */
        cursor_to (SELECTED_FRAME (), 0, 0);
  #endif
 +
 +      write_stdout ("Emacs is resuming after an emergency escape.\n");
 +
        /* It doesn't work to autosave while GC is in progress;
         the code used for auto-saving doesn't cope with the mark bit.  */
        if (!gc_in_progress)
@@@ -10980,6 -10964,8 +10988,8 @@@ syms_of_keyboard (void
    DEFSYM (Qpost_command_hook, "post-command-hook");
  
    DEFSYM (Qundo_auto__add_boundary, "undo-auto--add-boundary");
+   DEFSYM (Qundo_auto__undoably_changed_buffers,
+           "undo-auto--undoably-changed-buffers");
  
    DEFSYM (Qdeferred_action_function, "deferred-action-function");
    DEFSYM (Qdelayed_warnings_hook, "delayed-warnings-hook");
  
  #ifdef HAVE_NTGUI
    DEFSYM (Qlanguage_change, "language-change");
 +  DEFSYM (Qend_session, "end-session");
  #endif
  
  #ifdef HAVE_DBUS
@@@ -11738,25 -11723,6 +11748,25 @@@ Currently, the only supported values fo
  variable are `sigusr1' and `sigusr2'.  */);
    Vdebug_on_event = intern_c_string ("sigusr2");
  
 +  DEFVAR_BOOL ("attempt-stack-overflow-recovery",
 +               attempt_stack_overflow_recovery,
 +               doc: /* If non-nil, attempt to recover from C stack
 +overflow.  This recovery is unsafe and may lead to deadlocks or data
 +corruption, but it usually works and may preserve modified buffers
 +that would otherwise be lost.  If nil, treat stack overflow like any
 +other kind of crash.  */);
 +  attempt_stack_overflow_recovery = true;
 +
 +  DEFVAR_BOOL ("attempt-orderly-shutdown-on-fatal-signal",
 +               attempt_orderly_shutdown_on_fatal_signal,
 +               doc: /* If non-nil, attempt to perform an orderly
 +shutdown when Emacs receives a fatal signal (e.g., a crash).
 +This cleanup is unsafe and may lead to deadlocks or data corruption,
 +but it usually works and may preserve modified buffers that would
 +otherwise be lost.  If nil, crash immediately in response to fatal
 +signals.  */);
 +  attempt_orderly_shutdown_on_fatal_signal = true;
 +
    /* Create the initial keyboard.  Qt means 'unset'.  */
    initial_kboard = allocate_kboard (Qt);
  }
@@@ -11772,10 -11738,6 +11782,10 @@@ keys_of_keyboard (void
  
    initial_define_lispy_key (Vspecial_event_map, "delete-frame",
                            "handle-delete-frame");
 +#ifdef HAVE_NTGUI
 +  initial_define_lispy_key (Vspecial_event_map, "end-session",
 +                          "kill-emacs");
 +#endif
    initial_define_lispy_key (Vspecial_event_map, "ns-put-working-text",
                            "ns-put-working-text");
    initial_define_lispy_key (Vspecial_event_map, "ns-unput-working-text",
diff --combined src/syntax.c
index 1c1a2f827823107ba97400e52f22348a8a33efd7,0af2a21a220477b539acd2e492463a1093a1496e..587335acef8f4e8e1258dd0c4964f432e3c1f559
@@@ -81,11 -81,6 +81,11 @@@ SYNTAX_FLAGS_COMEND_SECOND (int flags
    return (flags >> 19) & 1;
  }
  static bool
 +SYNTAX_FLAGS_COMSTARTEND_FIRST (int flags)
 +{
 +  return (flags & 0x50000) != 0;
 +}
 +static bool
  SYNTAX_FLAGS_PREFIX (int flags)
  {
    return (flags >> 20) & 1;
@@@ -158,10 -153,6 +158,10 @@@ struct lisp_parse_stat
      ptrdiff_t comstr_start;  /* Position of last comment/string starter.  */
      Lisp_Object levelstarts; /* Char numbers of starts-of-expression
                                of levels (starting from outermost).  */
 +    int prev_syntax; /* Syntax of previous position scanned, when
 +                        that position (potentially) holds the first char
 +                        of a 2-char construct, i.e. comment delimiter
 +                        or Sescape, etc.  Smax otherwise. */
    };
  \f
  /* These variables are a cache for finding the start of a defun.
@@@ -185,8 -176,7 +185,8 @@@ static Lisp_Object skip_syntaxes (bool
  static Lisp_Object scan_lists (EMACS_INT, EMACS_INT, EMACS_INT, bool);
  static void scan_sexps_forward (struct lisp_parse_state *,
                                  ptrdiff_t, ptrdiff_t, ptrdiff_t, EMACS_INT,
 -                                bool, Lisp_Object, int);
 +                                bool, int);
 +static void internalize_parse_state (Lisp_Object, struct lisp_parse_state *);
  static bool in_classes (int, Lisp_Object);
  static void parse_sexp_propertize (ptrdiff_t charpos);
  
@@@ -708,7 -698,7 +708,7 @@@ back_comment (ptrdiff_t from, ptrdiff_
    ptrdiff_t comment_end = from;
    ptrdiff_t comment_end_byte = from_byte;
    ptrdiff_t comstart_pos = 0;
 -  ptrdiff_t comstart_byte IF_LINT (= 0);
 +  ptrdiff_t comstart_byte;
    /* Place where the containing defun starts,
       or 0 if we didn't come across it yet.  */
    ptrdiff_t defun_start = 0;
        }
        do
        {
 +          internalize_parse_state (Qnil, &state);
          scan_sexps_forward (&state,
                              defun_start, defun_start_byte,
                              comment_end, TYPE_MINIMUM (EMACS_INT),
 -                            0, Qnil, 0);
 +                            0, 0);
          defun_start = comment_end;
          if (!adjusted)
            {
@@@ -1633,7 -1622,7 +1633,7 @@@ skip_chars (bool forwardp, Lisp_Object 
    int c;
    char fastmap[0400];
    /* Store the ranges of non-ASCII characters.  */
 -  int *char_ranges IF_LINT (= NULL);
 +  int *char_ranges UNINIT;
    int n_char_ranges = 0;
    bool negate = 0;
    ptrdiff_t i, i_byte;
@@@ -2310,15 -2299,11 +2310,15 @@@ in_classes (int c, Lisp_Object iso_clas
     PREV_SYNTAX is the SYNTAX_WITH_FLAGS of the previous character
       (or 0 If the search cannot start in the middle of a two-character).
  
 -   If successful, return true and store the charpos of the comment's end
 -   into *CHARPOS_PTR and the corresponding bytepos into *BYTEPOS_PTR.
 -   Else, return false and store the charpos STOP into *CHARPOS_PTR, the
 -   corresponding bytepos into *BYTEPOS_PTR and the current nesting
 -   (as defined for state.incomment) in *INCOMMENT_PTR.
 +   If successful, return true and store the charpos of the comment's
 +   end into *CHARPOS_PTR and the corresponding bytepos into
 +   *BYTEPOS_PTR.  Else, return false and store the charpos STOP into
 +   *CHARPOS_PTR, the corresponding bytepos into *BYTEPOS_PTR and the
 +   current nesting (as defined for state->incomment) in
 +   *INCOMMENT_PTR.  Should the last character scanned in an incomplete
 +   comment be a possible first character of a two character construct,
 +   we store its SYNTAX_WITH_FLAGS into *last_syntax_ptr.  Otherwise,
 +   we store Smax into *last_syntax_ptr.
  
     The comment end is the last character of the comment rather than the
     character just after the comment.
@@@ -2330,7 -2315,7 +2330,7 @@@ static boo
  forw_comment (ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t stop,
              EMACS_INT nesting, int style, int prev_syntax,
              ptrdiff_t *charpos_ptr, ptrdiff_t *bytepos_ptr,
 -            EMACS_INT *incomment_ptr)
 +            EMACS_INT *incomment_ptr, int *last_syntax_ptr)
  {
    register int c, c1;
    register enum syntaxcode code;
    /* Enter the loop in the middle so that we find
       a 2-char comment ender if we start in the middle of it.  */
    syntax = prev_syntax;
 -  if (syntax != 0) goto forw_incomment;
 +  code = syntax & 0xff;
 +  if (syntax != 0 && from < stop) goto forw_incomment;
  
    while (1)
      {
          *incomment_ptr = nesting;
          *charpos_ptr = from;
          *bytepos_ptr = from_byte;
 +          *last_syntax_ptr =
 +            (code == Sescape || code == Scharquote
 +             || SYNTAX_FLAGS_COMEND_FIRST (syntax)
 +             || (nesting > 0
 +                 && SYNTAX_FLAGS_COMSTART_FIRST (syntax)))
 +            ? syntax : Smax ;
          return 0;
        }
        c = FETCH_CHAR_AS_MULTIBYTE (from_byte);
               SYNTAX_FLAGS_COMMENT_NESTED (other_syntax))
              ? nesting > 0 : nesting < 0))
        {
 -        if (--nesting <= 0)
 +        syntax = Smax;        /* So that "|#" (lisp) can not return
 +                                   the syntax of "#" in *last_syntax_ptr. */
 +          if (--nesting <= 0)
            /* We have encountered a comment end of the same style
               as the comment sequence which began this comment section.  */
            break;
        /* We have encountered a nested comment of the same style
           as the comment sequence which began this comment section.  */
        {
 +          syntax = Smax; /* So that "#|#" isn't also a comment ender. */
          INC_BOTH (from, from_byte);
          UPDATE_SYNTAX_TABLE_FORWARD (from);
          nesting++;
      }
    *charpos_ptr = from;
    *bytepos_ptr = from_byte;
 +  *last_syntax_ptr = Smax; /* Any syntactic power the last byte had is
 +                              used up. */
    return 1;
  }
  
@@@ -2452,7 -2425,6 +2452,7 @@@ between them, return t; otherwise retur
    EMACS_INT count1;
    ptrdiff_t out_charpos, out_bytepos;
    EMACS_INT dummy;
 +  int dummy2;
  
    CHECK_NUMBER (count);
    count1 = XINT (count);
        }
        /* We're at the start of a comment.  */
        found = forw_comment (from, from_byte, stop, comnested, comstyle, 0,
 -                          &out_charpos, &out_bytepos, &dummy);
 +                          &out_charpos, &out_bytepos, &dummy, &dummy2);
        from = out_charpos; from_byte = out_bytepos;
        if (!found)
        {
@@@ -2676,7 -2648,6 +2676,7 @@@ scan_lists (EMACS_INT from, EMACS_INT c
    ptrdiff_t from_byte;
    ptrdiff_t out_bytepos, out_charpos;
    EMACS_INT dummy;
 +  int dummy2;
    bool multibyte_symbol_p = sexpflag && multibyte_syntax_as_symbol;
  
    if (depth > 0) min_depth = 0;
              UPDATE_SYNTAX_TABLE_FORWARD (from);
              found = forw_comment (from, from_byte, stop,
                                    comnested, comstyle, 0,
 -                                  &out_charpos, &out_bytepos, &dummy);
 +                                  &out_charpos, &out_bytepos, &dummy,
 +                                    &dummy2);
              from = out_charpos, from_byte = out_bytepos;
              if (!found)
                {
@@@ -3138,7 -3108,7 +3138,7 @@@ the prefix syntax flag (p).  */
  }
  \f
  /* Parse forward from FROM / FROM_BYTE to END,
 -   assuming that FROM has state OLDSTATE (nil means FROM is start of function),
 +   assuming that FROM has state STATE,
     and return a description of the state of the parse at END.
     If STOPBEFORE, stop at the start of an atom.
     If COMMENTSTOP is 1, stop at the start of a comment.
     after the beginning of a string, or after the end of a string.  */
  
  static void
 -scan_sexps_forward (struct lisp_parse_state *stateptr,
 +scan_sexps_forward (struct lisp_parse_state *state,
                    ptrdiff_t from, ptrdiff_t from_byte, ptrdiff_t end,
                    EMACS_INT targetdepth, bool stopbefore,
 -                  Lisp_Object oldstate, int commentstop)
 +                  int commentstop)
  {
 -  struct lisp_parse_state state;
    enum syntaxcode code;
    int c1;
    bool comnested;
    Lisp_Object tem;
    ptrdiff_t prev_from;                /* Keep one character before FROM.  */
    ptrdiff_t prev_from_byte;
 -  int prev_from_syntax;
 +  int prev_from_syntax, prev_prev_from_syntax;
    bool boundary_stop = commentstop == -1;
    bool nofence;
    bool found;
  do { prev_from = from;                                \
       prev_from_byte = from_byte;              \
       temp = FETCH_CHAR_AS_MULTIBYTE (prev_from_byte); \
 +     prev_prev_from_syntax = prev_from_syntax;  \
       prev_from_syntax = SYNTAX_WITH_FLAGS (temp); \
       INC_BOTH (from, from_byte);              \
       if (from < end)                          \
    immediate_quit = 1;
    QUIT;
  
 -  if (NILP (oldstate))
 -    {
 -      depth = 0;
 -      state.instring = -1;
 -      state.incomment = 0;
 -      state.comstyle = 0;     /* comment style a by default.  */
 -      state.comstr_start = -1;        /* no comment/string seen.  */
 -    }
 -  else
 -    {
 -      tem = Fcar (oldstate);
 -      if (!NILP (tem))
 -      depth = XINT (tem);
 -      else
 -      depth = 0;
 -
 -      oldstate = Fcdr (oldstate);
 -      oldstate = Fcdr (oldstate);
 -      oldstate = Fcdr (oldstate);
 -      tem = Fcar (oldstate);
 -      /* Check whether we are inside string_fence-style string: */
 -      state.instring = (!NILP (tem)
 -                      ? (CHARACTERP (tem) ? XFASTINT (tem) : ST_STRING_STYLE)
 -                      : -1);
 -
 -      oldstate = Fcdr (oldstate);
 -      tem = Fcar (oldstate);
 -      state.incomment = (!NILP (tem)
 -                       ? (INTEGERP (tem) ? XINT (tem) : -1)
 -                       : 0);
 -
 -      oldstate = Fcdr (oldstate);
 -      tem = Fcar (oldstate);
 -      start_quoted = !NILP (tem);
 +  depth = state->depth;
 +  start_quoted = state->quoted;
 +  prev_prev_from_syntax = Smax;
 +  prev_from_syntax = state->prev_syntax;
  
 -      /* if the eighth element of the list is nil, we are in comment
 -       style a.  If it is non-nil, we are in comment style b */
 -      oldstate = Fcdr (oldstate);
 -      oldstate = Fcdr (oldstate);
 -      tem = Fcar (oldstate);
 -      state.comstyle = (NILP (tem)
 -                      ? 0
 -                      : (RANGED_INTEGERP (0, tem, ST_COMMENT_STYLE)
 -                         ? XINT (tem)
 -                         : ST_COMMENT_STYLE));
 -
 -      oldstate = Fcdr (oldstate);
 -      tem = Fcar (oldstate);
 -      state.comstr_start =
 -      RANGED_INTEGERP (PTRDIFF_MIN, tem, PTRDIFF_MAX) ? XINT (tem) : -1;
 -      oldstate = Fcdr (oldstate);
 -      tem = Fcar (oldstate);
 -      while (!NILP (tem))             /* >= second enclosing sexps.  */
 -      {
 -        Lisp_Object temhd = Fcar (tem);
 -        if (RANGED_INTEGERP (PTRDIFF_MIN, temhd, PTRDIFF_MAX))
 -          curlevel->last = XINT (temhd);
 -        if (++curlevel == endlevel)
 -          curlevel--; /* error ("Nesting too deep for parser"); */
 -        curlevel->prev = -1;
 -        curlevel->last = -1;
 -        tem = Fcdr (tem);
 -      }
 +  tem = state->levelstarts;
 +  while (!NILP (tem))         /* >= second enclosing sexps.  */
 +    {
 +      Lisp_Object temhd = Fcar (tem);
 +      if (RANGED_INTEGERP (PTRDIFF_MIN, temhd, PTRDIFF_MAX))
 +        curlevel->last = XINT (temhd);
 +      if (++curlevel == endlevel)
 +        curlevel--; /* error ("Nesting too deep for parser"); */
 +      curlevel->prev = -1;
 +      curlevel->last = -1;
 +      tem = Fcdr (tem);
      }
 -  state.quoted = 0;
 -  mindepth = depth;
 -
    curlevel->prev = -1;
    curlevel->last = -1;
  
 -  SETUP_SYNTAX_TABLE (prev_from, 1);
 -  temp = FETCH_CHAR (prev_from_byte);
 -  prev_from_syntax = SYNTAX_WITH_FLAGS (temp);
 -  UPDATE_SYNTAX_TABLE_FORWARD (from);
 +  state->quoted = 0;
 +  mindepth = depth;
 +
 +  SETUP_SYNTAX_TABLE (from, 1);
  
    /* Enter the loop at a place appropriate for initial state.  */
  
 -  if (state.incomment)
 +  if (state->incomment)
      goto startincomment;
 -  if (state.instring >= 0)
 +  if (state->instring >= 0)
      {
 -      nofence = state.instring != ST_STRING_STYLE;
 +      nofence = state->instring != ST_STRING_STYLE;
        if (start_quoted)
        goto startquotedinstring;
        goto startinstring;
    while (from < end)
      {
        int syntax;
 -      INC_FROM;
 -      code = prev_from_syntax & 0xff;
  
 -      if (from < end
 -        && SYNTAX_FLAGS_COMSTART_FIRST (prev_from_syntax)
 +      if (SYNTAX_FLAGS_COMSTART_FIRST (prev_from_syntax)
          && (c1 = FETCH_CHAR (from_byte),
              syntax = SYNTAX_WITH_FLAGS (c1),
              SYNTAX_FLAGS_COMSTART_SECOND (syntax)))
          /* Record the comment style we have entered so that only
             the comment-end sequence of the same style actually
             terminates the comment section.  */
 -        state.comstyle
 +        state->comstyle
            = SYNTAX_FLAGS_COMMENT_STYLE (syntax, prev_from_syntax);
          comnested = (SYNTAX_FLAGS_COMMENT_NESTED (prev_from_syntax)
                       | SYNTAX_FLAGS_COMMENT_NESTED (syntax));
 -        state.incomment = comnested ? 1 : -1;
 -        state.comstr_start = prev_from;
 +        state->incomment = comnested ? 1 : -1;
 +        state->comstr_start = prev_from;
          INC_FROM;
 +          prev_from_syntax = Smax; /* the syntax has already been
 +                                      "used up". */
          code = Scomment;
        }
 -      else if (code == Scomment_fence)
 -      {
 -        /* Record the comment style we have entered so that only
 -           the comment-end sequence of the same style actually
 -           terminates the comment section.  */
 -        state.comstyle = ST_COMMENT_STYLE;
 -        state.incomment = -1;
 -        state.comstr_start = prev_from;
 -        code = Scomment;
 -      }
 -      else if (code == Scomment)
 -      {
 -        state.comstyle = SYNTAX_FLAGS_COMMENT_STYLE (prev_from_syntax, 0);
 -        state.incomment = (SYNTAX_FLAGS_COMMENT_NESTED (prev_from_syntax) ?
 -                           1 : -1);
 -        state.comstr_start = prev_from;
 -      }
 +      else
 +        {
 +          INC_FROM;
 +          code = prev_from_syntax & 0xff;
 +          if (code == Scomment_fence)
 +            {
 +              /* Record the comment style we have entered so that only
 +                 the comment-end sequence of the same style actually
 +                 terminates the comment section.  */
 +              state->comstyle = ST_COMMENT_STYLE;
 +              state->incomment = -1;
 +              state->comstr_start = prev_from;
 +              code = Scomment;
 +            }
 +          else if (code == Scomment)
 +            {
 +              state->comstyle = SYNTAX_FLAGS_COMMENT_STYLE (prev_from_syntax, 0);
 +              state->incomment = (SYNTAX_FLAGS_COMMENT_NESTED (prev_from_syntax) ?
 +                                 1 : -1);
 +              state->comstr_start = prev_from;
 +            }
 +        }
  
        if (SYNTAX_FLAGS_PREFIX (prev_from_syntax))
        continue;
  
        case Scomment_fence: /* Can't happen because it's handled above.  */
        case Scomment:
 -        if (commentstop || boundary_stop) goto done;
 +          if (commentstop || boundary_stop) goto done;
        startincomment:
          /* The (from == BEGV) test was to enter the loop in the middle so
             that we find a 2-char comment ender even if we start in the
             middle of it.  We don't want to do that if we're just at the
             beginning of the comment (think of (*) ... (*)).  */
          found = forw_comment (from, from_byte, end,
 -                              state.incomment, state.comstyle,
 -                              (from == BEGV || from < state.comstr_start + 3)
 -                              ? 0 : prev_from_syntax,
 -                              &out_charpos, &out_bytepos, &state.incomment);
 +                              state->incomment, state->comstyle,
 +                              from == BEGV ? 0 : prev_from_syntax,
 +                              &out_charpos, &out_bytepos, &state->incomment,
 +                                &prev_from_syntax);
          from = out_charpos; from_byte = out_bytepos;
 -        /* Beware!  prev_from and friends are invalid now.
 -           Luckily, the `done' doesn't use them and the INC_FROM
 -           sets them to a sane value without looking at them. */
 +        /* Beware!  prev_from and friends (except prev_from_syntax)
 +           are invalid now.  Luckily, the `done' doesn't use them
 +           and the INC_FROM sets them to a sane value without
 +           looking at them. */
          if (!found) goto done;
          INC_FROM;
 -        state.incomment = 0;
 -        state.comstyle = 0;   /* reset the comment style */
 -        if (boundary_stop) goto done;
 +        state->incomment = 0;
 +        state->comstyle = 0;  /* reset the comment style */
 +        prev_from_syntax = Smax; /* For the comment closer */
 +          if (boundary_stop) goto done;
          break;
  
        case Sopen:
  
        case Sstring:
        case Sstring_fence:
 -        state.comstr_start = from - 1;
 +        state->comstr_start = from - 1;
          if (stopbefore) goto stop;  /* this arg means stop at sexp start */
          curlevel->last = prev_from;
 -        state.instring = (code == Sstring
 +        state->instring = (code == Sstring
                            ? (FETCH_CHAR_AS_MULTIBYTE (prev_from_byte))
                            : ST_STRING_STYLE);
          if (boundary_stop) goto done;
        startinstring:
          {
 -          nofence = state.instring != ST_STRING_STYLE;
 +          nofence = state->instring != ST_STRING_STYLE;
  
            while (1)
              {
                /* Check C_CODE here so that if the char has
                   a syntax-table property which says it is NOT
                   a string character, it does not end the string.  */
 -              if (nofence && c == state.instring && c_code == Sstring)
 +              if (nofence && c == state->instring && c_code == Sstring)
                  break;
  
                switch (c_code)
              }
          }
        string_end:
 -        state.instring = -1;
 +        state->instring = -1;
          curlevel->prev = curlevel->last;
          INC_FROM;
          if (boundary_stop) goto done;
   stop:   /* Here if stopping before start of sexp. */
    from = prev_from;    /* We have just fetched the char that starts it; */
    from_byte = prev_from_byte;
 +  prev_from_syntax = prev_prev_from_syntax;
    goto done; /* but return the position before it. */
  
   endquoted:
 -  state.quoted = 1;
 +  state->quoted = 1;
   done:
 -  state.depth = depth;
 -  state.mindepth = mindepth;
 -  state.thislevelstart = curlevel->prev;
 -  state.prevlevelstart
 +  state->depth = depth;
 +  state->mindepth = mindepth;
 +  state->thislevelstart = curlevel->prev;
 +  state->prevlevelstart
      = (curlevel == levelstart) ? -1 : (curlevel - 1)->last;
 -  state.location = from;
 -  state.location_byte = from_byte;
 -  state.levelstarts = Qnil;
 +  state->location = from;
 +  state->location_byte = from_byte;
 +  state->levelstarts = Qnil;
    while (curlevel > levelstart)
 -    state.levelstarts = Fcons (make_number ((--curlevel)->last),
 -                             state.levelstarts);
 +    state->levelstarts = Fcons (make_number ((--curlevel)->last),
 +                                state->levelstarts);
 +  state->prev_syntax = (SYNTAX_FLAGS_COMSTARTEND_FIRST (prev_from_syntax)
 +                        || state->quoted) ? prev_from_syntax : Smax;
    immediate_quit = 0;
 +}
 +
 +/* Convert a (lisp) parse state to the internal form used in
 +   scan_sexps_forward.  */
 +static void
 +internalize_parse_state (Lisp_Object external, struct lisp_parse_state *state)
 +{
 +  Lisp_Object tem;
 +
 +  if (NILP (external))
 +    {
 +      state->depth = 0;
 +      state->instring = -1;
 +      state->incomment = 0;
 +      state->quoted = 0;
 +      state->comstyle = 0;    /* comment style a by default.  */
 +      state->comstr_start = -1;       /* no comment/string seen.  */
 +      state->levelstarts = Qnil;
 +      state->prev_syntax = Smax;
 +    }
 +  else
 +    {
 +      tem = Fcar (external);
 +      if (!NILP (tem))
 +      state->depth = XINT (tem);
 +      else
 +      state->depth = 0;
 +
 +      external = Fcdr (external);
 +      external = Fcdr (external);
 +      external = Fcdr (external);
 +      tem = Fcar (external);
 +      /* Check whether we are inside string_fence-style string: */
 +      state->instring = (!NILP (tem)
 +                         ? (CHARACTERP (tem) ? XFASTINT (tem) : ST_STRING_STYLE)
 +                         : -1);
 +
 +      external = Fcdr (external);
 +      tem = Fcar (external);
 +      state->incomment = (!NILP (tem)
 +                          ? (INTEGERP (tem) ? XINT (tem) : -1)
 +                          : 0);
 +
 +      external = Fcdr (external);
 +      tem = Fcar (external);
 +      state->quoted = !NILP (tem);
  
 -  *stateptr = state;
 +      /* if the eighth element of the list is nil, we are in comment
 +       style a.  If it is non-nil, we are in comment style b */
 +      external = Fcdr (external);
 +      external = Fcdr (external);
 +      tem = Fcar (external);
 +      state->comstyle = (NILP (tem)
 +                         ? 0
 +                         : (RANGED_INTEGERP (0, tem, ST_COMMENT_STYLE)
 +                            ? XINT (tem)
 +                            : ST_COMMENT_STYLE));
 +
 +      external = Fcdr (external);
 +      tem = Fcar (external);
 +      state->comstr_start =
 +      RANGED_INTEGERP (PTRDIFF_MIN, tem, PTRDIFF_MAX) ? XINT (tem) : -1;
 +      external = Fcdr (external);
 +      tem = Fcar (external);
 +      state->levelstarts = tem;
 +
 +      external = Fcdr (external);
 +      tem = Fcar (external);
 +      state->prev_syntax = NILP (tem) ? Smax : XINT (tem);
 +    }
  }
  
  DEFUN ("parse-partial-sexp", Fparse_partial_sexp, Sparse_partial_sexp, 2, 6, 0,
@@@ -3534,7 -3477,6 +3534,7 @@@ Parsing stops at TO or when certain cri
   point is set to where parsing stops.
  If fifth arg OLDSTATE is omitted or nil,
   parsing assumes that FROM is the beginning of a function.
 +
  Value is a list of elements describing final state of parsing:
   0. depth in parens.
   1. character address of start of innermost containing list; nil if none.
   6. the minimum paren-depth encountered during this scan.
   7. style of comment, if any.
   8. character address of start of comment or string; nil if not in one.
 - 9. Intermediate data for continuation of parsing (subject to change).
 + 9. List of positions of currently open parens, outermost first.
 +10. When the last position scanned holds the first character of a
 +    (potential) two character construct, the syntax of that position,
 +    otherwise nil.  That construct can be a two character comment
 +    delimiter or an Escaped or Char-quoted character.
 +11..... Possible further internal information used by `parse-partial-sexp'.
 +
  If third arg TARGETDEPTH is non-nil, parsing stops if the depth
  in parentheses becomes equal to TARGETDEPTH.
 -Fourth arg STOPBEFORE non-nil means stop when come to
 +Fourth arg STOPBEFORE non-nil means stop when we come to
   any character that starts a sexp.
  Fifth arg OLDSTATE is a list like what this function returns.
   It is used to initialize the state of the parse.  Elements number 1, 2, 6
   are ignored.
 -Sixth arg COMMENTSTOP non-nil means stop at the start of a comment.
 - If it is symbol `syntax-table', stop after the start of a comment or a
 +Sixth arg COMMENTSTOP non-nil means stop after the start of a comment.
 + If it is the symbol `syntax-table', stop after the start of a comment or a
   string, or after end of a comment or a string.  */)
    (Lisp_Object from, Lisp_Object to, Lisp_Object targetdepth,
     Lisp_Object stopbefore, Lisp_Object oldstate, Lisp_Object commentstop)
      target = TYPE_MINIMUM (EMACS_INT);        /* We won't reach this depth.  */
  
    validate_region (&from, &to);
 +  internalize_parse_state (oldstate, &state);
    scan_sexps_forward (&state, XINT (from), CHAR_TO_BYTE (XINT (from)),
                      XINT (to),
 -                    target, !NILP (stopbefore), oldstate,
 +                    target, !NILP (stopbefore),
                      (NILP (commentstop)
                       ? 0 : (EQ (commentstop, Qsyntax_table) ? -1 : 1)));
  
    SET_PT_BOTH (state.location, state.location_byte);
  
 -  return Fcons (make_number (state.depth),
 +  return
 +    Fcons (make_number (state.depth),
           Fcons (state.prevlevelstart < 0
                  ? Qnil : make_number (state.prevlevelstart),
             Fcons (state.thislevelstart < 0
                                  ? Qsyntax_table
                                  : make_number (state.comstyle))
                               : Qnil),
 -                            Fcons (((state.incomment
 -                                     || (state.instring >= 0))
 -                                    ? make_number (state.comstr_start)
 -                                    : Qnil),
 -                                   Fcons (state.levelstarts, Qnil))))))))));
 +                       Fcons (((state.incomment
 +                                  || (state.instring >= 0))
 +                                 ? make_number (state.comstr_start)
 +                                 : Qnil),
 +                         Fcons (state.levelstarts,
 +                             Fcons (state.prev_syntax == Smax
 +                                    ? Qnil
 +                                    : make_number (state.prev_syntax),
 +                                Qnil)))))))))));
  }
  \f
  void
@@@ -3771,7 -3701,7 +3771,7 @@@ In both cases, LIMIT bounds the search
    Vfind_word_boundary_function_table = Fmake_char_table (Qnil, Qnil);
  
    DEFVAR_BOOL ("comment-end-can-be-escaped", Vcomment_end_can_be_escaped,
-                doc: /* Non-nil means an escaped ender inside a comment doesn'tend the comment.  */);
+                doc: /* Non-nil means an escaped ender inside a comment doesn't end the comment.  */);
    Vcomment_end_can_be_escaped = 0;
    DEFSYM (Qcomment_end_can_be_escaped, "comment-end-can-be-escaped");
    Fmake_variable_buffer_local (Qcomment_end_can_be_escaped);
index 12ebc75ea9284a824274eb13010a8e103363d613,40cd1d29498f95d4fcbacd4ded021bb18c48dfb1..40cd1d29498f95d4fcbacd4ded021bb18c48dfb1
     (= 6
        (undo-test-point-after-forward-kill))))
  
+ (defmacro simple-test-undo-with-switched-buffer (buffer &rest body)
+   (let ((before-buffer (make-symbol "before-buffer")))
+     `(let ((,before-buffer (current-buffer)))
+        (unwind-protect
+            (progn
+              (switch-to-buffer ,buffer)
+              ,@body)
+          (switch-to-buffer ,before-buffer)))))
+ ;; This tests for a regression in emacs 25.0 see bug #23632
+ (ert-deftest simple-test-undo-extra-boundary-in-tex ()
+   (should
+    (string=
+     ""
+     (simple-test-undo-with-switched-buffer
+         "temp.tex"
+       (latex-mode)
+       ;; This macro calls `latex-insert-block'
+       (execute-kbd-macro
+        (read-kbd-macro
+         "
+ C-c C-o                       ;; latex-insert-block
+ RET                   ;; newline
+ C-/                     ;; undo
+ "
+         ))
+       (buffer-substring-no-properties
+        (point-min)
+        (point-max))))))
  
  (provide 'simple-test)
  ;;; simple-test.el ends here