]> git.eshelyaron.com Git - emacs.git/commitdiff
-
authorPaul Eggert <eggert@cs.ucla.edu>
Tue, 22 Mar 2016 18:01:30 +0000 (11:01 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Tue, 22 Mar 2016 18:01:30 +0000 (11:01 -0700)
23 files changed:
1  2 
configure.ac
doc/emacs/maintaining.texi
doc/lispref/sequences.texi
etc/NEWS
lisp/dired-x.el
lisp/gnus/mml-sec.el
lisp/gnus/mml-smime.el
lisp/gnus/mml1991.el
lisp/gnus/mml2015.el
lisp/international/characters.el
lisp/international/mule-cmds.el
lisp/loadup.el
lisp/progmodes/cc-defs.el
lisp/progmodes/cc-engine.el
lisp/progmodes/elisp-mode.el
src/editfns.c
src/image.c
src/keyboard.c
src/xdisp.c
src/xfns.c
test/lisp/emacs-lisp/package-tests.el
test/lisp/progmodes/ruby-mode-tests.el
test/manual/indent/ruby.rb

diff --cc configure.ac
Simple merge
Simple merge
index 002a9ceceec43befde7e8729d242d54d12e1bd99,a54ab104ab55408807b0e488e7fb9c407afd9849..f7d26e54d0bd19449e1337f626387811461329c9
@@@ -572,26 -576,12 +576,27 @@@ element of @var{sequence}.  The returne
  @end example
  @end defun
  
 +@defun seq-map-indexed function sequence
 +  This function returns the result of applying @var{function} to each
 +element of @var{sequence} and its index within @var{seq}.  The
 +returned value is a list.
 +
 +@example
 +@group
 +(seq-map-indexed (lambda (elt idx)
 +                   (list idx elt))
 +                 '(a b c))
 +@result{} ((0 a) (b 1) (c 2))
 +@end group
 +@end example
 +@end defun
 +
  @defun seq-mapn function &rest sequences
    This function returns the result of applying @var{function} to each
- element of @var{sequences}.  The arity of @var{function} must match
- the number of sequences.  Mapping stops at the shortest sequence, and
- the returned value is a list.
+ element of @var{sequences}.  The arity (@pxref{What Is a Function,
+ sub-arity}) of @var{function} must match the number of sequences.
+ Mapping stops at the end of the shortest sequence, and the returned
+ value is a list.
  
  @example
  @group
diff --cc etc/NEWS
index 4414625eacd4d83fa3a2db7e26396fd4a3860d42,8ce194a69cab5a9e9a21afaa343aed6aa7a6d591..366208b27da68db2c2a84ab80ccf56c3362c2fea
+++ b/etc/NEWS
@@@ -22,183 -22,6 +22,183 @@@ Temporary note
  When you add a new item, use the appropriate mark if you are sure it applies,
  otherwise leave it unmarked.
  
- ** New configure option ‘--disable-build-details’ attempts to build an
 +\f
 +* Installation Changes in Emacs 25.2
 +
 ++++
- ** A number of accessors for the value returned by `file-attributes'
- has 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'
++** 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
 +
 ++++
- ** The locale language name `ca' is now mapped to the language
- environment `Catalan', which has been added.
++** A number of accessors for the value returned by 'file-attributes'
++has 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'
 +
 +---
- ** `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 locale language name 'ca' is now mapped to the language
++environment 'Catalan', which has been added.
 +
 +---
- `make-network-process').  How asynchronous it is varies based on the
++** '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
- Certain process oriented functions (like `process-datagram-address')
++'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).
 +
- ** ‘make-network-process’ and ‘open-network-stream’ sometimes allowed
++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.
 +
- fatal signal.  `attempt-stack-overflow-recovery', if set to `nil',
++** '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 allow to disable attempts to recover from stack
 +overflow and to avoid automatic auto-save when Emacs is delivered a
- `attempt-orderly-shutdown-on-fatal-signal', if set to `nil', will
++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.
- terminate immediately.  Both variables are non-`nil' by default.
++'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
- *** A new `s' command for switching to another eww buffer via the minibuffer.
++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.
 +
 +\f
 +* Editing Changes in Emacs 25.2
 +
 +\f
 +* Changes in Specialized Modes and Packages in Emacs 25.2
 +
 +** eww
 +
 ++++
- *** The `o' command (`shr-save-contents') has moved to `O' to avoid collision
- with the `o' command from `image-map'.
++*** A new 's' command for switching to another eww buffer via the minibuffer.
 +
 +---
- `change-log-directory-files' to nil for the old behavior.
++*** The 'o' command ('shr-save-contents') has moved to 'O' to avoid collision
++with the 'o' command from 'image-map'.
 +
 ++++
 +** The commands that add ChangeLog entries now prefer a VCS root directory
 +for the ChangeLog file, if none already exists.  Customize
- ** Support for non-string values of `time-stamp-format' has been removed.
++'change-log-directory-files' to nil for the old behavior.
 +
 +---
- ** `auto-revert-use-notify' is set back to t in `global-auto-revert-mode'.
++** Support for non-string values of 'time-stamp-format' has been removed.
 +
 +** Tramp
 +
 ++++
 +*** New connection method "sg", which allows to edit files under
 +different group ID.
 +
 ++++
 +*** New connection method "doas" for OpenBSD hosts.
 +
 +---
- ** Resizing a frame no longer runs `window-configuration-change-hook'.
- Put your function on `window-size-change-functions' instead.
++** 'auto-revert-use-notify' is set back to t in 'global-auto-revert-mode'.
 +
 +\f
 +* New Modes and Packages in Emacs 25.2
 +
 +\f
 +* Incompatible Lisp Changes in Emacs 25.2
 +
 ++++
- by setting `autoload-timestamps' to nil.
++** Resizing a frame no longer runs 'window-configuration-change-hook'.
++Put your function on 'window-size-change-functions' instead.
 +
 +\f
 +* Lisp Changes in Emacs 25.2
 +
 +** New var syntax-ppss-table to control the syntax-table used in syntax-ppss
 +
 +** Autoload files can be generated without timestamps,
- ** `ert-with-function-mocked' of 'ert-x package allows mocking of functions
++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
++** 'ert-with-function-mocked' of 'ert-x package allows mocking of functions
 +in unit tests.
 +
 +---
- ** New functions `window-pixel-width-before-size-change' and
- `window-pixel-height-before-size-change' allow to detect which window
- changed size when `window-size-change-functions' are run.
++** 'gnutls-boot' now takes a parameter :complete-negotiation that says
 +that negotiation should complete even on non-blocking sockets.
 +
 ++++
- ** New function `display-buffer-reuse-mode-window' is an action function
- suitable for use in `display-buffer-alist'. For example, to avoid creating
++** New functions 'window-pixel-width-before-size-change' and
++'window-pixel-height-before-size-change' allow to detect which window
++changed size when 'window-size-change-functions' are run.
 +
 ++++
-      '("\\`\\*Man .*\\*\\'" .
++** 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
- ** `parse-partial-sexp' state has a new element.  Element 10 is
++     '("\\'\\*Man .*\\*\\'" .
 +       (display-buffer-reuse-mode-window
 +        (inhibit-same-window . nil)
 +        (mode . Man-mode))))
 +
 ++++
- ** `parse-partial-sexp''s state, element 9, has now been confirmed as
++** '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.
 +
 ++++
- system.  This makes the `w32-register-hot-key' functionality work
++** '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.
 +
 +\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.)
 +
  \f
  * Installation Changes in Emacs 25.1
  
@@@ -354,36 -177,20 +354,35 @@@ object
  
  Loadable modules in Emacs are an experimental feature, and subject to
  change in future releases.  For that reason, their support is disabled
- by default, and must be enabled by using the `--with-modules' option
+ by default, and must be enabled by using the '--with-modules' option
  at configure time.
  
- See the variable `dir-locals-file-2' for more information.
 ++++
 +** A second dir-local file (.dir-locals-2.el) is now accepted.
++See the variable 'dir-locals-file-2' for more information.
 +
  +++
  ** Network security (TLS/SSL certificate validity and the like) is
  added via the new Network Security Manager (NSM) and controlled via
- the `network-security-level' variable.
+ the 'network-security-level' variable.
  
- puny.el library, so that one can visit web sites like
- "http://méxico.icom.museum".
 +---
 +** International domain names (IDNA) are now encoded via the new
++puny.el library, so that one can visit web sites with non-ASCII URLs.
 +
  +++
  ** C-h l now also lists the commands that were run.
  
 +** The new M-s M-w key binding uses eww to search the web for the
 +text in the region.
 +
  +++
- ** The new `timer-list' command lists all active timers in a buffer
- where you can cancel them with the `c' command.
 -** x-select-enable-clipboard is renamed select-enable-clipboard
 -and x-select-enable-primary is renamed select-enable-primary.
++** The new 'timer-list' command lists all active timers in a buffer
++where you can cancel them with the 'c' command.
 +
 +** M-x suggests shorthands and ignores obsolete commands for completion.
 +** x-select-enable-clipboard is renamed select-enable-clipboard.
 +x-select-enable-primary and renamed select-enable-primary.
  Additionally they both now apply to all systems (OSX, GNUstep, Windows, you
  name it), with the proviso that on some systems (e.g. Windows)
  select-enable-primary is ineffective since the system doesn't
@@@ -395,13 -202,9 +394,13 @@@ customize how 'switch-to-buffer' procee
  selected window is strongly dedicated to its buffer.
  
  +++
- ** The option `even-window-heights' has been renamed to
`even-window-sizes' and now handles window widths as well.
+ ** The option 'even-window-heights' has been renamed to
'even-window-sizes' and now handles window widths as well.
  
- ** New function `read-multiple-choice' use to prompt for
 ++++
++** New function 'read-multiple-choice' use to prompt for
 +multiple-choice questions, with a handy way to display help texts.
 +
  +++
  ** terpri gets an optional arg ENSURE to conditionally output a newline.
  
@@@ -519,15 -323,10 +519,15 @@@ unsaved customizations and prompts use
  is intended for adding to 'kill-emacs-query-functions'.
  
  +++
- ** The old `C-x w' bindings in hi-lock-mode are officially deprecated
- in favor of the global `M-s h' bindings introduced in Emacs-23.1.
+ ** The old 'C-x w' bindings in hi-lock-mode are officially deprecated
+ in favor of the global 'M-s h' bindings introduced in Emacs-23.1.
  They'll disappear soon.
  
- `undo', undo the last replacement; bound to `u'.
- `undo-all', undo all replacements; bound to `U'.
 ++++
 +** 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.1
  
@@@ -654,13 -453,10 +654,13 @@@ obsolete alias for the new 'save-place-
  
  +++
  *** ERC can now hide message types by network or channel.
`erc-hide-list' will hide all messages of the specified type, while
`erc-network-hide-list' and `erc-channel-hide-list' will only hide the
'erc-hide-list' will hide all messages of the specified type, while
'erc-network-hide-list' and 'erc-channel-hide-list' will only hide the
  specified message types for the respective specified targets.
  
- *** New variable `erc-default-port-tls' used to connect to TLS IRC
++*** New variable 'erc-default-port-tls' used to connect to TLS IRC
 +servers.
 +
  ---
  *** Reconnection is now asynchronous.
  
@@@ -905,31 -703,19 +907,31 @@@ using mono-spaced font
  *** HTML can now be rendered using variable-width fonts.
  
  +++
- *** A new command `F' (`eww-toggle-fonts') can be used to toggle
+ *** A new command 'F' ('eww-toggle-fonts') can be used to toggle
  whether to use variable-pitch fonts or not.  The user can also
- customize the `shr-use-fonts' variable.
+ customize the 'shr-use-fonts' variable.
  
- *** A new command `C' (`eww-toggle-colors') can be used to toggle
 ++++
- customize the `shr-use-colors' variable.
++*** 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.
 +
  +++
- *** A new command `R' (`eww-readable') will try do identify the main
+ *** A new command 'R' ('eww-readable') will try do identify the main
  textual parts of a web page and display only that, leaving menus and
  the like off the page.
  
  +++
- *** A new command `D' (`eww-toggle-paragraph-direction') allows you to
+ *** A new command 'D' ('eww-toggle-paragraph-direction') allows you to
  toggle the paragraph direction between left-to-right and right-to-left.
  
 +---
 +*** Images that are being loaded are now marked with grey
 +"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).
 +
  ---
  *** You can now use several eww buffers in parallel by renaming eww
  buffers you want to keep separate.
@@@ -969,17 -755,6 +971,17 @@@ invalid certificates are marked in red
  *** text/html messages that contain inline image parts will be
  transformed into multipart/related messages before sending.
  
- *** The `message-valid-fqdn-regexp' variable has been removed, since
 +---
- *** `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.
++*** 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.
 +
  +++
  ** In Show Paren Mode, a parenthesis can be highlighted when point
  stands inside it, and certain parens can be highlighted when point is
@@@ -989,32 -764,8 +991,32 @@@ respectively, 'show-paren-when-point-in
  
  ---
  ** If gpg2 exists on the system, it is now used as the default value
- of `epg-gpg-program' (instead of gpg).
+ of 'epg-gpg-program' (instead of gpg).
  
- `image-scaling-factor' variable (if Emacs supports scaling the images
 +** Images
 +
 ++++
 +*** Images are automatically scaled before displaying based on the
- *** Images inserted with `insert-image' and related functions get a
++'image-scaling-factor' variable (if Emacs supports scaling the images
 +in question).
 +
 ++++
- also available in `image-mode'.
++*** 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
- provided: `image-property'.
++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'.
 +
 +
  ** Lisp mode
  
  ---
@@@ -1186,13 -937,8 +1188,13 @@@ variable, meaning you can bind it aroun
  ---
  *** If URL is used with a https connection, the first callback argument
  plist will contain a :peer element that has the output of
`gnutls-peer-status' (if Emacs is built with GnuTLS support).
'gnutls-peer-status' (if Emacs is built with GnuTLS support).
  
- *** The new function `url-cookie-delete-cookie' can be used to
 ++++
++*** The new function 'url-cookie-delete-cookie' can be used to
 +programmatically delete all cookies, or cookies from a specific
 +domain.
 +
  ** Tramp
  
  +++
@@@ -1242,14 -988,9 +1244,14 @@@ This command is useful when you perfor
  outside Emacs (e.g., from the shell prompt), or if you switch the VC
  back-end for the buffer's file, or remove it from version control.
  
- See the `vc-faces' customization group.
 +---
 +*** 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.
 +
  +++
- *** New option `vc-annotate-background-mode' controls whether
- the color range from `vc-annotate-color-map' is applied to the
+ *** New option 'vc-annotate-background-mode' controls whether
+ the color range from 'vc-annotate-color-map' is applied to the
  background or to the foreground.
  
  +++
@@@ -1518,30 -1259,21 +1520,30 @@@ notification descriptor still correspon
  directories and decompress zip files.
  
  +++
- *** New command `dired-do-compress-to' bound to `c' can be used to
+ *** New command 'dired-do-compress-to' bound to 'c' can be used to
  compress many marked files into a single named archive.  The
  compression command is determined from the new
`dired-compress-files-alist' variable.
'dired-compress-files-alist' variable.
  
  +++
- `wdired-create-parent-directories' variable.
 +*** In wdired, when editing files to contain slash characters,
 +the resulting directories are automatically created.  Whether
 +to do this or not is controlled by the
- *** `W' is now bound to `browse-url-of-dired-file', and is useful for
++'wdired-create-parent-directories' variable.
 +
 ++++
- *** New user interface for the `A' and `Q' commands.
- These keys, now bound to `dired-do-find-regexp' and
- `dired-do-find-regexp-and-replace', work similarly to `xref-find-apropos'
- and `xref-query-replace-in-results': they present the matches
- in the `*xref*' buffer and let you move through the matches.  No need
- to use `tags-loop-continue' to resume the search or replace loop.  The
- previous commands, `dired-do-search' and
- `dired-do-query-replace-regexp', are still available, but not bound to
- keys; rebind `A' and `Q' to invoke them if you want the old behavior
++*** 'W' is now bound to 'browse-url-of-dired-file', and is useful for
 +viewing HTML files and the like.
 +
+ *** New user interface for the 'A' and 'Q' commands.
+ These keys, now bound to 'dired-do-find-regexp' and
+ 'dired-do-find-regexp-and-replace', work similarly to 'xref-find-apropos'
+ and 'xref-query-replace-in-results': they present the matches
+ in the '*xref*' buffer and let you move through the matches.  No need
+ to use 'tags-loop-continue' to resume the search or replace loop.  The
+ previous commands, 'dired-do-search' and
+ 'dired-do-query-replace-regexp', are still available, but not bound to
+ keys; rebind 'A' and 'Q' to invoke them if you want the old behavior
  back.  We intend to obsolete the old commands in a future release.
  
  ** Tabulated List Mode
@@@ -1675,24 -1407,16 +1677,24 @@@ symbol-function was changed not to sign
  ** Comint, term, and compile do not set the EMACS env var any more.
  Use the INSIDE_EMACS environment variable instead.
  
- ** `C-up', `C-down', `C-left' and `C-right' are now defined in term
++** '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.'
++mode bindings: 'C-c @ C-a',  'C-c @ C-t',  'C-c @ C-d', and 'C-c @ C-e.'
 +
  +++
- ** `save-excursion' does not save&restore the mark any more.
- Use `save-mark-and-excursion' if you want the old behavior.
+ ** 'save-excursion' does not save&restore the mark any more.
+ Use 'save-mark-and-excursion' if you want the old behavior.
  
  +++
- ** `read-buffer' and `read-buffer-function' can now be called with a 4th
- argument (`predicate').
+ ** 'read-buffer' and 'read-buffer-function' can now be called with a 4th
+ argument ('predicate').
  
  +++
- ** `completion-table-dynamic' by default stays in the minibuffer.
+ ** 'completion-table-dynamic' by default stays in the minibuffer.
  The minibuffer will be the current buffer when the function is called.
  If you want the old behavior of calling the function in the buffer
  from which the minibuffer was entered, use the new argument
@@@ -1777,20 -1501,16 +1779,20 @@@ behavior, set 'diff-switches' to '-c'
  dynamically.  Any third-party code that changes these templates should
  be updated accordingly.
  
- before running.  This is controlled by the `grep-save-buffers'
 +** The grep/rgrep/lgrep functions will now ask about saving files
++before running.  This is controlled by the 'grep-save-buffers'
 +variable.
 +
  +++
- ** ‘(/ N)’ is now equivalent to ‘(/ 1 N)’ rather than to ‘(/ N 1)’.
+ ** '(/ N)' is now equivalent to '(/ 1 N)' rather than to '(/ N 1)'.
  The new behavior is compatible with Common Lisp and with XEmacs.
  This change does not affect Lisp code intended to be portable to
- Emacs 24.2 and earlier, which did not support unary ‘/’.
+ Emacs 24.2 and earlier, which did not support unary '/'.
  
  +++
- ** The `default-directory' value doesn't have to end slash.  To make
- that happen, `unhandled-file-name-directory' now defaults to calling
`file-name-as-directory'.
+ ** The 'default-directory' value doesn't have to end slash.  To make
+ that happen, 'unhandled-file-name-directory' now defaults to calling
'file-name-as-directory'.
  
  \f
  * Lisp Changes in Emacs 25.1
@@@ -1886,10 -1606,6 +1888,10 @@@ details
  It should be placed right where the docstring would be, and FORM is then
  evaluated (and should return a string) when the closure is built.
  
- ** The new command `fortune-message' has been added, which displays
 +---
++** The new command 'fortune-message' has been added, which displays
 +fortunes in the echo area.
 +
  +++
  ** define-inline provides a new way to define inlinable functions.
  
  preserve the collation order as defined by the system's locale(1)
  environment.  For the time being this is implemented for modern POSIX
  systems and for MS-Windows, for other systems they fall back to their
- counterparts `string-lessp' and `string-equal'.
+ counterparts 'string-lessp' and 'string-equal'.
  
- ** The new function `string-version-lessp' compares strings by
 ++++
++** 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 ls-lisp package uses `string-collate-lessp' to sort file names.
+ *** The ls-lisp package uses 'string-collate-lessp' to sort file names.
  The effect is that, on systems that use ls-lisp for Dired, the default
  sort order of the files in Dired is now different from what it was in
  previous versions of Emacs.  In particular, the file names are sorted
@@@ -2100,25 -1810,17 +2102,25 @@@ if the terminal cannot display curved q
  +++
  ** Standard output and error streams now transliterate characters via
  standard-display-table, and encode output using locale-coding-system.
- To force a specific encoding, bind `coding-system-for-write' to the
- coding-system of your choice when invoking functions like `prin1' and
`message'.
+ To force a specific encoding, bind 'coding-system-for-write' to the
+ coding-system of your choice when invoking functions like 'prin1' and
'message'.
  
  +++
- ** New var `truncate-string-ellipsis' to choose how to indicate truncation.
+ ** New var 'truncate-string-ellipsis' to choose how to indicate truncation.
  
  +++
- ** New possible value for `system-type': `nacl'.
+ ** New possible value for 'system-type': 'nacl'.
  This is used by Google's Native Client (NaCl).
  
- ** `read-color' will now display the color names using the color itself
 +---
- ** There is now a new variable `flyspell-sort-corrections-function'
++** 'read-color' will now display the color names using the color itself
 +as the background color.
 +
 +---
++** There is now a new variable 'flyspell-sort-corrections-function'
 +that allows changing the way corrections are sorted.
 +
  ** Miscellaneous name change
  
  ---
diff --cc lisp/dired-x.el
Simple merge
index 576eceecf4bc2945b6586007720a9cfadd827399,254c427299e9d1584dac92734f303152ef693b1a..0e2d4381993664cd6d9277e187a05bec615d7c58
  (autoload 'mml-smime-verify "mml-smime")
  (autoload 'mml-smime-verify-test "mml-smime")
  (autoload 'epa--select-keys "epa")
 +(autoload 'message-options-get "message")
 +(autoload 'message-options-set "message")
  
+ (declare-function message-options-set "message" (symbol value))
  (defvar mml-sign-alist
    '(("smime"     mml-smime-sign-buffer     mml-smime-sign-query)
      ("pgp"       mml-pgp-sign-buffer       list)
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc lisp/loadup.el
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc src/editfns.c
Simple merge
diff --cc src/image.c
Simple merge
diff --cc src/keyboard.c
Simple merge
diff --cc src/xdisp.c
Simple merge
diff --cc src/xfns.c
Simple merge
index 9afdfe67c26437edcd9dfc476ae56d567b3bdb44,0000000000000000000000000000000000000000..70e129cc4f577384eea360c653308ced0e17d9af
mode 100644,000000..100644
--- /dev/null
@@@ -1,626 -1,0 +1,626 @@@
-                        t)
 +;;; package-test.el --- Tests for the Emacs package system
 +
 +;; Copyright (C) 2013-2016 Free Software Foundation, Inc.
 +
 +;; Author: Daniel Hackney <dan@haxney.org>
 +;; Version: 1.0
 +
 +;; This file is part of GNU Emacs.
 +
 +;; GNU Emacs is free software: you can redistribute it and/or modify
 +;; it under the terms of the GNU General Public License as published by
 +;; the Free Software Foundation, either version 3 of the License, or
 +;; (at your option) any later version.
 +
 +;; GNU Emacs is distributed in the hope that it will be useful,
 +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +;; GNU General Public License for more details.
 +
 +;; You should have received a copy of the GNU General Public License
 +;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 +
 +;;; Commentary:
 +
 +;; You may want to run this from a separate Emacs instance from your
 +;; main one, because a bug in the code below could mess with your
 +;; installed packages.
 +
 +;; Run this in a clean Emacs session using:
 +;;
 +;;     $ emacs -Q --batch -L . -l package-test.el -l ert -f ert-run-tests-batch-and-exit
 +
 +;;; Code:
 +
 +(require 'package)
 +(require 'ert)
 +(require 'cl-lib)
 +
 +(setq package-menu-async nil)
 +
 +(defvar package-test-user-dir nil
 +  "Directory to use for installing packages during testing.")
 +
 +(defvar package-test-file-dir (file-name-directory (or load-file-name
 +                                                       buffer-file-name))
 +  "Directory of the actual \"package-test.el\" file.")
 +
 +(defvar simple-single-desc
 +  (package-desc-create :name 'simple-single
 +                       :version '(1 3)
 +                       :summary "A single-file package with no dependencies"
 +                       :kind 'single
 +                       :extras '((:authors ("J. R. Hacker" . "jrh@example.com"))
 +                                 (:maintainer "J. R. Hacker" . "jrh@example.com")
 +                                 (:url . "http://doodles.au")))
 +  "Expected `package-desc' parsed from simple-single-1.3.el.")
 +
 +(defvar simple-depend-desc
 +  (package-desc-create :name 'simple-depend
 +                       :version '(1 0)
 +                       :summary "A single-file package with a dependency."
 +                       :kind 'single
 +                       :reqs '((simple-single (1 3)))
 +                       :extras '((:authors ("J. R. Hacker" . "jrh@example.com"))
 +                                 (:maintainer "J. R. Hacker" . "jrh@example.com")))
 +  "Expected `package-desc' parsed from simple-depend-1.0.el.")
 +
 +(defvar multi-file-desc
 +  (package-desc-create :name 'multi-file
 +                       :version '(0 2 3)
 +                       :summary "Example of a multi-file tar package"
 +                       :kind 'tar
 +                       :extras '((:url . "http://puddles.li")))
 +  "Expected `package-desc' from \"multi-file-0.2.3.tar\".")
 +
 +(defvar new-pkg-desc
 +  (package-desc-create :name 'new-pkg
 +                       :version '(1 0)
 +                       :kind 'single)
 +  "Expected `package-desc' parsed from new-pkg-1.0.el.")
 +
 +(defvar simple-depend-desc-1
 +  (package-desc-create :name 'simple-depend-1
 +                       :version '(1 0)
 +                       :summary "A single-file package with a dependency."
 +                       :kind 'single
 +                       :reqs '((simple-depend (1 0))
 +                               (multi-file (0 1))))
 +  "`package-desc' used for testing dependencies.")
 +
 +(defvar simple-depend-desc-2
 +  (package-desc-create :name 'simple-depend-2
 +                       :version '(1 0)
 +                       :summary "A single-file package with a dependency."
 +                       :kind 'single
 +                       :reqs '((simple-depend-1 (1 0))
 +                               (multi-file (0 1))))
 +  "`package-desc' used for testing dependencies.")
 +
 +(defvar package-test-data-dir (expand-file-name "package-resources" package-test-file-dir)
 +  "Base directory of package test files.")
 +
 +(defvar package-test-fake-contents-file
 +  (expand-file-name "archive-contents" package-test-data-dir)
 +  "Path to a static copy of \"archive-contents\".")
 +
 +(cl-defmacro with-package-test ((&optional &key file
 +                                           basedir
 +                                           install
 +                                           location
 +                                           update-news
 +                                           upload-base)
 +                                &rest body)
 +  "Set up temporary locations and variables for testing."
 +  (declare (indent 1))
 +  `(let* ((package-test-user-dir (make-temp-file "pkg-test-user-dir-" t))
 +          (process-environment (cons (format "HOME=%s" package-test-user-dir)
 +                                     process-environment))
 +          (package-user-dir package-test-user-dir)
 +          (package-archives `(("gnu" . ,(or ,location package-test-data-dir))))
 +          (default-directory package-test-file-dir)
 +          abbreviated-home-dir
 +          package--initialized
 +          package-alist
 +          ,@(if update-news
 +                '(package-update-news-on-upload t)
 +              (list (cl-gensym)))
 +          ,@(if upload-base
 +                '((package-test-archive-upload-base (make-temp-file "pkg-archive-base-" t))
 +                  (package-archive-upload-base package-test-archive-upload-base))
 +              (list (cl-gensym)))) ;; Dummy value so `let' doesn't try to bind nil
 +     (let ((buf (get-buffer "*Packages*")))
 +       (when (buffer-live-p buf)
 +         (kill-buffer buf)))
 +     (unwind-protect
 +         (progn
 +           ,(if basedir `(cd ,basedir))
 +           (unless (file-directory-p package-user-dir)
 +             (mkdir package-user-dir))
 +           (cl-letf (((symbol-function 'yes-or-no-p) (lambda (&rest r) t))
 +                     ((symbol-function 'y-or-n-p)    (lambda (&rest r) t)))
 +             ,@(when install
 +                 `((package-initialize)
 +                   (package-refresh-contents)
 +                   (mapc 'package-install ,install)))
 +             (with-temp-buffer
 +               ,(if file
 +                    `(insert-file-contents ,file))
 +               ,@body)))
 +
 +       (when (file-directory-p package-test-user-dir)
 +         (delete-directory package-test-user-dir t))
 +
 +       (when (and (boundp 'package-test-archive-upload-base)
 +                  (file-directory-p package-test-archive-upload-base))
 +         (delete-directory package-test-archive-upload-base t)))))
 +
 +(defmacro with-fake-help-buffer (&rest body)
 +  "Execute BODY in a temp buffer which is treated as the \"*Help*\" buffer."
 +  `(with-temp-buffer
 +    (help-mode)
 +    ;; Trick `help-buffer' into using the temp buffer.
 +    (let ((help-xref-following t))
 +      ,@body)))
 +
 +(defun package-test-strip-version (dir)
 +  (replace-regexp-in-string "-pkg\\.el\\'" "" (package--description-file dir)))
 +
 +(defun package-test-suffix-matches (base suffix-list)
 +  "Return file names matching BASE concatenated with each item in SUFFIX-LIST"
 +  (cl-mapcan
 +   '(lambda (item) (file-expand-wildcards (concat base item)))
 +   suffix-list))
 +
 +(defvar tar-parse-info)
 +(declare-function tar-header-name "tar-mode" (cl-x) t) ; defstruct
 +
 +(defun package-test-search-tar-file (filename)
 +  "Search the current buffer's `tar-parse-info' variable for FILENAME.
 +
 +Must called from within a `tar-mode' buffer."
 +  (cl-dolist (header tar-parse-info)
 +    (let ((tar-name (tar-header-name header)))
 +      (when (string= tar-name filename)
 +        (cl-return t)))))
 +
 +(defun package-test-desc-version-string (desc)
 +  "Return the package version as a string."
 +  (package-version-join (package-desc-version desc)))
 +
 +(ert-deftest package-test-desc-from-buffer ()
 +  "Parse an elisp buffer to get a `package-desc' object."
 +  (with-package-test (:basedir "package-resources" :file "simple-single-1.3.el")
 +    (should (equal (package-buffer-info) simple-single-desc)))
 +  (with-package-test (:basedir "package-resources" :file "simple-depend-1.0.el")
 +    (should (equal (package-buffer-info) simple-depend-desc)))
 +  (with-package-test (:basedir "package-resources"
 +                               :file "multi-file-0.2.3.tar")
 +    (tar-mode)
 +    (should (equal (package-tar-file-info) multi-file-desc))))
 +
 +(ert-deftest package-test-install-single ()
 +  "Install a single file without using an archive."
 +  (with-package-test (:basedir "package-resources" :file "simple-single-1.3.el")
 +    (should (package-install-from-buffer))
 +    (package-initialize)
 +    (should (package-installed-p 'simple-single))
 +    ;; Check if we properly report an "already installed".
 +    (package-install 'simple-single)
 +    (with-current-buffer "*Messages*"
 +      (should (string-match "^[`‘']simple-single[’'] is already installed\n?\\'"
 +                            (buffer-string))))
 +    (should (package-installed-p 'simple-single))
 +    (let* ((simple-pkg-dir (file-name-as-directory
 +                            (expand-file-name
 +                             "simple-single-1.3"
 +                             package-test-user-dir)))
 +           (autoloads-file (expand-file-name "simple-single-autoloads.el"
 +                                             simple-pkg-dir)))
 +      (should (file-directory-p simple-pkg-dir))
 +      (with-temp-buffer
 +        (insert-file-contents (expand-file-name "simple-single-pkg.el"
 +                                                simple-pkg-dir))
 +        (should (string= (buffer-string)
 +                         (concat ";;; -*- no-byte-compile: t -*-\n"
 +                                 "(define-package \"simple-single\" \"1.3\" "
 +                                 "\"A single-file package "
 +                                 "with no dependencies\" 'nil "
 +                                 ":authors '((\"J. R. Hacker\" . \"jrh@example.com\")) "
 +                                 ":maintainer '(\"J. R. Hacker\" . \"jrh@example.com\") "
 +                                 ":url \"http://doodles.au\""
 +                                 ")\n"))))
 +      (should (file-exists-p autoloads-file))
 +      (should-not (get-file-buffer autoloads-file)))))
 +
 +(ert-deftest package-test-install-dependency ()
 +  "Install a package which includes a dependency."
 +  (with-package-test ()
 +    (package-initialize)
 +    (package-refresh-contents)
 +    (package-install 'simple-depend)
 +    (should (package-installed-p 'simple-single))
 +    (should (package-installed-p 'simple-depend))))
 +
 +(ert-deftest package-test-macro-compilation ()
 +  "Install a package which includes a dependency."
 +  (with-package-test (:basedir "package-resources")
 +    (package-install-file (expand-file-name "macro-problem-package-1.0/"))
 +    (require 'macro-problem)
 +    ;; `macro-problem-func' uses a macro from `macro-aux'.
 +    (should (equal (macro-problem-func) '(progn a b)))
 +    (package-install-file (expand-file-name "macro-problem-package-2.0/"))
 +    ;; After upgrading, `macro-problem-func' depends on a new version
 +    ;; of the macro from `macro-aux'.
 +    (should (equal (macro-problem-func) '(1 b)))
 +    ;; `macro-problem-10-and-90' depends on an entirely new macro from `macro-aux'.
 +    (should (equal (macro-problem-10-and-90) '(10 90)))))
 +
 +(ert-deftest package-test-install-two-dependencies ()
 +  "Install a package which includes a dependency."
 +  (with-package-test ()
 +    (package-initialize)
 +    (package-refresh-contents)
 +    (package-install 'simple-two-depend)
 +    (should (package-installed-p 'simple-single))
 +    (should (package-installed-p 'simple-depend))
 +    (should (package-installed-p 'simple-two-depend))))
 +
 +(ert-deftest package-test-refresh-contents ()
 +  "Parse an \"archive-contents\" file."
 +  (with-package-test ()
 +    (package-initialize)
 +    (package-refresh-contents)
 +    (should (eq 4 (length package-archive-contents)))))
 +
 +(ert-deftest package-test-install-single-from-archive ()
 +  "Install a single package from a package archive."
 +  (with-package-test ()
 +    (package-initialize)
 +    (package-refresh-contents)
 +    (package-install 'simple-single)))
 +
 +(ert-deftest package-test-install-prioritized ()
 +  "Install a lower version from a higher-prioritized archive."
 +  (with-package-test ()
 +    (let* ((newer-version (expand-file-name "package-resources/newer-versions"
 +                                            package-test-file-dir))
 +           (package-archives `(("older" . ,package-test-data-dir)
 +                               ("newer" . ,newer-version)))
 +           (package-archive-priorities '(("older" . 100))))
 +
 +      (package-initialize)
 +      (package-refresh-contents)
 +      (package-install 'simple-single)
 +
 +      (let ((installed (cadr (assq 'simple-single package-alist))))
 +        (should (version-list-= '(1 3)
 +                                (package-desc-version installed)))))))
 +
 +(ert-deftest package-test-install-multifile ()
 +  "Check properties of the installed multi-file package."
 +  (with-package-test (:basedir "package-resources" :install '(multi-file))
 +    (let ((autoload-file
 +           (expand-file-name "multi-file-autoloads.el"
 +                             (expand-file-name
 +                              "multi-file-0.2.3"
 +                              package-test-user-dir)))
 +          (installed-files '("dir" "multi-file.info" "multi-file-sub.elc"
 +                             "multi-file-autoloads.el" "multi-file.elc"))
 +          (autoload-forms '("^(defvar multi-file-custom-var"
 +                            "^(custom-autoload 'multi-file-custom-var"
 +                            "^(autoload 'multi-file-mode"))
 +          (pkg-dir (file-name-as-directory
 +                    (expand-file-name
 +                     "multi-file-0.2.3"
 +                     package-test-user-dir))))
 +      (package-refresh-contents)
 +      (should (package-installed-p 'multi-file))
 +      (with-temp-buffer
 +        (insert-file-contents-literally autoload-file)
 +        (dolist (fn installed-files)
 +          (should (file-exists-p (expand-file-name fn pkg-dir))))
 +        (dolist (re autoload-forms)
 +          (goto-char (point-min))
 +          (should (re-search-forward re nil t)))))))
 +
 +(ert-deftest package-test-update-listing ()
 +  "Ensure installed package status is updated."
 +  (with-package-test ()
 +    (let ((buf (package-list-packages)))
 +      (search-forward-regexp "^ +simple-single")
 +      (package-menu-mark-install)
 +      (package-menu-execute)
 +      (run-hooks 'post-command-hook)
 +      (should (package-installed-p 'simple-single))
 +      (switch-to-buffer "*Packages*")
 +      (goto-char (point-min))
 +      (should (re-search-forward "^\\s-+simple-single\\s-+1.3\\s-+installed" nil t))
 +      (goto-char (point-min))
 +      (should-not (re-search-forward "^\\s-+simple-single\\s-+1.3\\s-+\\(available\\|new\\)" nil t))
 +      (kill-buffer buf))))
 +
 +(ert-deftest package-test-update-archives ()
 +  "Test updating package archives."
 +  (with-package-test ()
 +    (let ((buf (package-list-packages)))
 +      (package-menu-refresh)
 +      (search-forward-regexp "^ +simple-single")
 +      (package-menu-mark-install)
 +      (package-menu-execute)
 +      (should (package-installed-p 'simple-single))
 +      (let ((package-test-data-dir
 +             (expand-file-name "package-resources/newer-versions" package-test-file-dir)))
 +        (setq package-archives `(("gnu" . ,package-test-data-dir)))
 +        (package-menu-refresh)
 +
 +        ;; New version should be available and old version should be installed
 +        (goto-char (point-min))
 +        (should (re-search-forward "^\\s-+simple-single\\s-+1.4\\s-+available" nil t))
 +        (should (re-search-forward "^\\s-+simple-single\\s-+1.3\\s-+installed" nil t))
 +
 +        (goto-char (point-min))
 +        (should (re-search-forward "^\\s-+new-pkg\\s-+1.0\\s-+\\(available\\|new\\)" nil t))
 +
 +        (package-menu-mark-upgrades)
 +        (package-menu-execute)
 +        (package-menu-refresh)
 +        (should (package-installed-p 'simple-single '(1 4)))))))
 +
 +(ert-deftest package-test-update-archives-async ()
 +  "Test updating package archives asynchronously."
 +  (skip-unless (executable-find "python2"))
 +  ;; For some reason this test doesn't work reliably on hydra.nixos.org.
 +  (skip-unless (not (getenv "NIX_STORE")))
 +  (with-package-test (:basedir
 +                      package-test-data-dir
 +                      :location "http://0.0.0.0:8000/")
 +    (let* ((package-menu-async t)
 +           (process (start-process
 +                     "package-server" "package-server-buffer"
 +                     (executable-find "python2")
 +                     (expand-file-name "package-test-server.py"))))
 +      (unwind-protect
 +          (progn
 +            (list-packages)
 +            (should package--downloads-in-progress)
 +            (should mode-line-process)
 +            (should-not
 +             (with-timeout (10 'timeout)
 +               (while package--downloads-in-progress
 +                 (accept-process-output nil 1))
 +               nil))
 +            ;; If the server process died, there's some non-Emacs problem.
 +            ;; Eg maybe the port was already in use.
 +            (skip-unless (process-live-p process))
 +            (goto-char (point-min))
 +            (should
 +             (search-forward-regexp "^ +simple-single" nil t)))
 +        (if (process-live-p process) (kill-process process))))))
 +
 +(ert-deftest package-test-describe-package ()
 +  "Test displaying help for a package."
 +
 +  (require 'finder-inf)
 +  ;; Built-in
 +  (with-fake-help-buffer
 +   (describe-package '5x5)
 +   (goto-char (point-min))
 +   (should (search-forward "5x5 is a built-in package." nil t))
 +   ;; Don't assume the descriptions are in any particular order.
 +   (save-excursion (should (search-forward "Status: Built-in." nil t)))
 +   (save-excursion (should (search-forward "Summary: simple little puzzle game" nil t)))
 +   (should (search-forward "The aim of 5x5" nil t)))
 +
 +  ;; Installed
 +  (with-package-test ()
 +    (package-initialize)
 +    (package-refresh-contents)
 +    (package-install 'simple-single)
 +    (with-fake-help-buffer
 +     (describe-package 'simple-single)
 +     (goto-char (point-min))
 +     (should (search-forward "simple-single is an installed package." nil t))
 +     (save-excursion (should (re-search-forward "Status: Installed in ['`‘]simple-single-1.3/['’] (unsigned)." nil t)))
 +     (save-excursion (should (search-forward "Version: 1.3" nil t)))
 +     (save-excursion (should (search-forward "Summary: A single-file package with no dependencies" nil t)))
 +     (save-excursion (should (search-forward "Homepage: http://doodles.au" nil t)))
 +     (save-excursion (should (re-search-forward "Keywords: \\[?frobnicate\\]?" nil t)))
 +     ;; No description, though. Because at this point we don't know
 +     ;; what archive the package originated from, and we don't have
 +     ;; its readme file saved.
 +     )))
 +
 +(ert-deftest package-test-describe-non-installed-package ()
 +  "Test displaying of the readme for non-installed package."
 +
 +  (with-package-test ()
 +    (package-initialize)
 +    (package-refresh-contents)
 +    (with-fake-help-buffer
 +     (describe-package 'simple-single)
 +     (goto-char (point-min))
 +     (should (search-forward "Homepage: http://doodles.au" nil t))
 +     (should (search-forward "This package provides a minor mode to frobnicate"
 +                             nil t)))))
 +
 +(ert-deftest package-test-describe-non-installed-multi-file-package ()
 +  "Test displaying of the readme for non-installed multi-file package."
 +
 +  (with-package-test ()
 +    (package-initialize)
 +    (package-refresh-contents)
 +    (with-fake-help-buffer
 +     (describe-package 'multi-file)
 +     (goto-char (point-min))
 +     (should (search-forward "Homepage: http://puddles.li" nil t))
 +     (should (search-forward "This is a bare-bones readme file for the multi-file"
 +                             nil t)))))
 +
 +(ert-deftest package-test-signed ()
 +  "Test verifying package signature."
 +  (skip-unless (ignore-errors
 +               (let ((homedir (make-temp-file "package-test" t)))
 +                 (unwind-protect
 +                     (let ((process-environment
 +                            (cons (format "HOME=%s" homedir)
 +                                  process-environment)))
 +                       (epg-check-configuration (epg-configuration))
++                       (epg-find-configuration 'OpenPGP))
 +                   (delete-directory homedir t)))))
 +  (let* ((keyring (expand-file-name "key.pub" package-test-data-dir))
 +       (package-test-data-dir
 +         (expand-file-name "package-resources/signed" package-test-file-dir)))
 +    (with-package-test ()
 +      (package-initialize)
 +      (package-import-keyring keyring)
 +      (package-refresh-contents)
 +      (should (package-install 'signed-good))
 +      (should-error (package-install 'signed-bad))
 +      ;; Check if the installed package status is updated.
 +      (let ((buf (package-list-packages)))
 +      (package-menu-refresh)
 +      (should (re-search-forward
 +               "^\\s-+signed-good\\s-+\\(\\S-+\\)\\s-+\\(\\S-+\\)\\s-"
 +               nil t))
 +      (should (string-equal (match-string-no-properties 1) "1.0"))
 +      (should (string-equal (match-string-no-properties 2) "installed")))
 +      ;; Check if the package description is updated.
 +      (with-fake-help-buffer
 +       (describe-package 'signed-good)
 +       (goto-char (point-min))
 +       (should (re-search-forward "signed-good is an? \\(\\S-+\\) package." nil t))
 +       (should (string-equal (match-string-no-properties 1) "installed"))
 +       (should (re-search-forward
 +              "Status: Installed in ['`‘]signed-good-1.0/['’]."
 +              nil t))))))
 +
 +
 +\f
 +;;; Tests for package-x features.
 +
 +(require 'package-x)
 +
 +(defvar package-x-test--single-archive-entry-1-3
 +  (cons 'simple-single
 +        (package-make-ac-desc '(1 3) nil
 +                              "A single-file package with no dependencies"
 +                              'single
 +                              '((:authors ("J. R. Hacker" . "jrh@example.com"))
 +                                (:maintainer "J. R. Hacker" . "jrh@example.com")
 +                                (:url . "http://doodles.au"))))
 +  "Expected contents of the archive entry from the \"simple-single\" package.")
 +
 +(defvar package-x-test--single-archive-entry-1-4
 +  (cons 'simple-single
 +        (package-make-ac-desc '(1 4) nil
 +                              "A single-file package with no dependencies"
 +                              'single
 +                              '((:authors ("J. R. Hacker" . "jrh@example.com"))
 +                                (:maintainer "J. R. Hacker" . "jrh@example.com"))))
 +  "Expected contents of the archive entry from the updated \"simple-single\" package.")
 +
 +(ert-deftest package-x-test-upload-buffer ()
 +  "Test creating an \"archive-contents\" file"
 +  (with-package-test (:basedir "package-resources"
 +                               :file "simple-single-1.3.el"
 +                               :upload-base t)
 +    (package-upload-buffer)
 +    (should (file-exists-p (expand-file-name "archive-contents"
 +                                             package-archive-upload-base)))
 +    (should (file-exists-p (expand-file-name "simple-single-1.3.el"
 +                                             package-archive-upload-base)))
 +    (should (file-exists-p (expand-file-name "simple-single-readme.txt"
 +                                             package-archive-upload-base)))
 +
 +    (let (archive-contents)
 +      (with-temp-buffer
 +        (insert-file-contents
 +         (expand-file-name "archive-contents"
 +                           package-archive-upload-base))
 +        (setq archive-contents
 +              (package-read-from-string
 +               (buffer-substring (point-min) (point-max)))))
 +      (should (equal archive-contents
 +                     (list 1 package-x-test--single-archive-entry-1-3))))))
 +
 +(ert-deftest package-x-test-upload-new-version ()
 +  "Test uploading a new version of a package"
 +  (with-package-test (:basedir "package-resources"
 +                               :file "simple-single-1.3.el"
 +                               :upload-base t)
 +    (package-upload-buffer)
 +    (with-temp-buffer
 +      (insert-file-contents "newer-versions/simple-single-1.4.el")
 +      (package-upload-buffer))
 +
 +    (let (archive-contents)
 +      (with-temp-buffer
 +        (insert-file-contents
 +         (expand-file-name "archive-contents"
 +                           package-archive-upload-base))
 +        (setq archive-contents
 +              (package-read-from-string
 +               (buffer-substring (point-min) (point-max)))))
 +      (should (equal archive-contents
 +                     (list 1 package-x-test--single-archive-entry-1-4))))))
 +
 +(ert-deftest package-test-get-deps ()
 +  "Test `package--get-deps' with complex structures."
 +  (let ((package-alist
 +         (mapcar (lambda (p) (list (package-desc-name p) p))
 +           (list simple-single-desc
 +                 simple-depend-desc
 +                 multi-file-desc
 +                 new-pkg-desc
 +                 simple-depend-desc-1
 +                 simple-depend-desc-2))))
 +    (should
 +     (equal (package--get-deps 'simple-depend)
 +            '(simple-single)))
 +    (should
 +     (equal (package--get-deps 'simple-depend 'indirect)
 +            nil))
 +    (should
 +     (equal (package--get-deps 'simple-depend 'direct)
 +            '(simple-single)))
 +    (should
 +     (equal (package--get-deps 'simple-depend-2)
 +            '(simple-depend-1 multi-file simple-depend simple-single)))
 +    (should
 +     (equal (package--get-deps 'simple-depend-2 'indirect)
 +            '(simple-depend multi-file simple-single)))
 +    (should
 +     (equal (package--get-deps 'simple-depend-2 'direct)
 +            '(simple-depend-1 multi-file)))))
 +
 +(ert-deftest package-test-sort-by-dependence ()
 +  "Test `package--sort-by-dependence' with complex structures."
 +  (let ((package-alist
 +         (mapcar (lambda (p) (list (package-desc-name p) p))
 +           (list simple-single-desc
 +                 simple-depend-desc
 +                 multi-file-desc
 +                 new-pkg-desc
 +                 simple-depend-desc-1
 +                 simple-depend-desc-2)))
 +        (delete-list
 +         (list simple-single-desc
 +               simple-depend-desc
 +               multi-file-desc
 +               new-pkg-desc
 +               simple-depend-desc-1
 +               simple-depend-desc-2)))
 +    (should
 +     (equal (package--sort-by-dependence delete-list)
 +
 +            (list simple-depend-desc-2 simple-depend-desc-1 new-pkg-desc
 +                  multi-file-desc simple-depend-desc simple-single-desc)))
 +    (should
 +     (equal (package--sort-by-dependence (reverse delete-list))
 +            (list new-pkg-desc simple-depend-desc-2 simple-depend-desc-1
 +                  multi-file-desc simple-depend-desc simple-single-desc)))))
 +
 +(provide 'package-test)
 +
 +;;; package-test.el ends here
index 4fa7470218afad8c0115c2be3110d34e83e11bce,0000000000000000000000000000000000000000..7e85fb83eddf25ada143a09665753a4e8a5a38c4
mode 100644,000000..100644
--- /dev/null
@@@ -1,730 -1,0 +1,738 @@@
 +;;; ruby-mode-tests.el --- Test suite for ruby-mode
 +
 +;; Copyright (C) 2012-2016 Free Software Foundation, Inc.
 +
 +;; This file is part of GNU Emacs.
 +
 +;; GNU Emacs is free software: you can redistribute it and/or modify
 +;; it under the terms of the GNU General Public License as published by
 +;; the Free Software Foundation, either version 3 of the License, or
 +;; (at your option) any later version.
 +
 +;; GNU Emacs is distributed in the hope that it will be useful,
 +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 +;; GNU General Public License for more details.
 +
 +;; You should have received a copy of the GNU General Public License
 +;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 +
 +;;; Commentary:
 +
 +;;; Code:
 +
 +(require 'ert)
 +(require 'ruby-mode)
 +
 +(defmacro ruby-with-temp-buffer (contents &rest body)
 +  (declare (indent 1) (debug t))
 +  `(with-temp-buffer
 +     (insert ,contents)
 +     (ruby-mode)
 +     ,@body))
 +
 +(defun ruby-should-indent (content column)
 +  "Assert indentation COLUMN on the last line of CONTENT."
 +  (ruby-with-temp-buffer content
 +    (indent-according-to-mode)
 +    (should (= (current-indentation) column))))
 +
 +(defun ruby-should-indent-buffer (expected content)
 +  "Assert that CONTENT turns into EXPECTED after the buffer is re-indented.
 +
 +The whitespace before and including \"|\" on each line is removed."
 +  (ruby-with-temp-buffer (ruby-test-string content)
 +    (indent-region (point-min) (point-max))
 +    (should (string= (ruby-test-string expected) (buffer-string)))))
 +
 +(defun ruby-test-string (s &rest args)
 +  (apply 'format (replace-regexp-in-string "^[ \t]*|" "" s) args))
 +
 +(defun ruby-assert-state (content index value &optional point)
 +  "Assert syntax state values at the end of CONTENT.
 +
 +VALUES-PLIST is a list with alternating index and value elements."
 +  (ruby-with-temp-buffer content
 +    (when point (goto-char point))
 +    (syntax-propertize (point))
 +    (should (eq (nth index
 +                     (parse-partial-sexp (point-min) (point)))
 +                value))))
 +
 +(defun ruby-assert-face (content pos face)
 +  (ruby-with-temp-buffer content
 +    (font-lock-ensure nil nil)
 +    (should (eq face (get-text-property pos 'face)))))
 +
 +(ert-deftest ruby-indent-after-symbol-made-from-string-interpolation ()
 +  "It can indent the line after symbol made using string interpolation."
 +  (ruby-should-indent "def foo(suffix)\n  :\"bar#{suffix}\"\n"
 +                      ruby-indent-level))
 +
 +(ert-deftest ruby-indent-after-js-style-symbol-with-block-beg-name ()
 +  "JS-style hash symbol can have keyword name."
 +  (ruby-should-indent "link_to \"home\", home_path, class: \"foo\"\n" 0))
 +
 +(ert-deftest ruby-discern-singleton-class-from-heredoc ()
 +  (ruby-assert-state "foo <<asd\n" 3 ?\n)
 +  (ruby-assert-state "class <<asd\n" 3 nil))
 +
 +(ert-deftest ruby-heredoc-font-lock ()
 +  (let ((s "foo <<eos.gsub('^ *', '')"))
 +    (ruby-assert-face s 9 font-lock-string-face)
 +    (ruby-assert-face s 10 nil)))
 +
 +(ert-deftest ruby-singleton-class-no-heredoc-font-lock ()
 +  (ruby-assert-face "class<<a" 8 nil))
 +
 +(ert-deftest ruby-heredoc-highlights-interpolations ()
 +  (ruby-assert-face "s = <<EOS\n  #{foo}\nEOS" 15 font-lock-variable-name-face))
 +
 +(ert-deftest ruby-no-heredoc-inside-quotes ()
 +  (ruby-assert-state "\"<<\", \"\",\nfoo" 3 nil))
 +
 +(ert-deftest ruby-no-heredoc-left-shift ()
 +  ;; We can't really detect the left shift operator (like in similar
 +  ;; cases, it depends on the type of foo), so we just require for <<
 +  ;; to be preceded by a character from a known set.
 +  (ruby-assert-state "foo(a<<b)" 3 nil))
 +
 +(ert-deftest ruby-no-heredoc-class-self ()
 +  (ruby-assert-state "class <<self\nend" 3 nil))
 +
 +(ert-deftest ruby-exit!-font-lock ()
 +  (ruby-assert-face "exit!" 5 font-lock-builtin-face))
 +
 +(ert-deftest ruby-deep-indent ()
 +  (let ((ruby-deep-arglist nil)
 +        (ruby-deep-indent-paren '(?\( ?\{ ?\[ ?\] t)))
 +    (ruby-should-indent "foo = [1,\n2" 7)
 +    (ruby-should-indent "foo = {a: b,\nc: d" 7)
 +    (ruby-should-indent "foo(a,\nb" 4)))
 +
 +(ert-deftest ruby-deep-indent-disabled ()
 +  (let ((ruby-deep-arglist nil)
 +        (ruby-deep-indent-paren nil))
 +    (ruby-should-indent "foo = [\n1" ruby-indent-level)
 +    (ruby-should-indent "foo = {\na: b" ruby-indent-level)
 +    (ruby-should-indent "foo(\na" ruby-indent-level)))
 +
 +(ert-deftest ruby-indent-after-keyword-in-a-string ()
 +  (ruby-should-indent "a = \"abc\nif\"\n  " 0)
 +  (ruby-should-indent "a = %w[abc\n       def]\n  " 0)
 +  (ruby-should-indent "a = \"abc\n      def\"\n  " 0))
 +
 +(ert-deftest ruby-regexp-doesnt-start-in-string ()
 +  (ruby-assert-state "'(/', /\d+/" 3 nil))
 +
 +(ert-deftest ruby-regexp-starts-after-string ()
 +  (ruby-assert-state "'(/', /\d+/" 3 ?/ 8))
 +
 +(ert-deftest ruby-regexp-interpolation-is-highlighted ()
 +  (ruby-assert-face "/#{foobs}/" 4 font-lock-variable-name-face))
 +
 +(ert-deftest ruby-regexp-skips-over-interpolation ()
 +  (ruby-assert-state "/#{foobs.join('/')}/" 3 nil))
 +
 +(ert-deftest ruby-regexp-continues-till-end-when-unclosed ()
 +  (ruby-assert-state "/bars" 3 ?/))
 +
 +(ert-deftest ruby-regexp-can-be-multiline ()
 +  (ruby-assert-state "/bars\ntees # toots \nfoos/" 3 nil))
 +
 +(ert-deftest ruby-slash-symbol-is-not-mistaken-for-regexp ()
 +  (ruby-assert-state ":/" 3 nil))
 +
 +(ert-deftest ruby-slash-char-literal-is-not-mistaken-for-regexp ()
 +  (ruby-assert-state "?/" 3 nil))
 +
 +(ert-deftest ruby-indent-simple ()
 +  (ruby-should-indent-buffer
 +   "if foo
 +   |  bar
 +   |end
 +   |zot
 +   |"
 +   "if foo
 +   |bar
 +   |  end
 +   |    zot
 +   |"))
 +
 +(ert-deftest ruby-indent-keyword-label ()
 +  (ruby-should-indent-buffer
 +   "bar(class: XXX) do
 +   |  foo
 +   |end
 +   |bar
 +   |"
 +   "bar(class: XXX) do
 +   |     foo
 +   |  end
 +   |    bar
 +   |"))
 +
 +(ert-deftest ruby-indent-method-with-question-mark ()
 +  (ruby-should-indent-buffer
 +   "if x.is_a?(XXX)
 +   |  foo
 +   |end
 +   |"
 +   "if x.is_a?(XXX)
 +   | foo
 +   |   end
 +   |"))
 +
 +(ert-deftest ruby-indent-expr-in-regexp ()
 +  (ruby-should-indent-buffer
 +   "if /#{foo}/ =~ s
 +   |  x = 1
 +   |end
 +   |"
 +   "if /#{foo}/ =~ s
 +   | x = 1
 +   |  end
 +   |"))
 +
 +(ert-deftest ruby-indent-singleton-class ()
 +  (ruby-should-indent-buffer
 +   "class<<bar
 +   |  foo
 +   |end
 +   |"
 +   "class<<bar
 +   |foo
 +   |   end
 +   |"))
 +
 +(ert-deftest ruby-indent-inside-heredoc-after-operator ()
 +  (ruby-should-indent-buffer
 +   "b=<<eos
 +   |     42"
 +   "b=<<eos
 +   |     42"))
 +
 +(ert-deftest ruby-indent-inside-heredoc-after-space ()
 +  (ruby-should-indent-buffer
 +   "foo <<eos.gsub(' ', '*')
 +   |     42"
 +   "foo <<eos.gsub(' ', '*')
 +   |     42"))
 +
 +(ert-deftest ruby-indent-array-literal ()
 +  (let ((ruby-deep-indent-paren nil))
 +    (ruby-should-indent-buffer
 +     "foo = [
 +     |  bar
 +     |]
 +     |"
 +     "foo = [
 +     | bar
 +     |  ]
 +     |"))
 +  (ruby-should-indent-buffer
 +   "foo do
 +   |  [bar]
 +   |end
 +   |"
 +   "foo do
 +   |[bar]
 +   |  end
 +   |"))
 +
 +(ert-deftest ruby-indent-begin-end ()
 +  (ruby-should-indent-buffer
 +   "begin
 +   |  a[b]
 +   |end
 +   |"
 +   "begin
 +   | a[b]
 +   |  end
 +   |"))
 +
 +(ert-deftest ruby-indent-array-after-paren-and-space ()
 +  (ruby-should-indent-buffer
 +   "class A
 +   |  def foo
 +   |    foo( [])
 +   |  end
 +   |end
 +   |"
 +   "class A
 +   | def foo
 +   |foo( [])
 +   |end
 +   |  end
 +   |"))
 +
 +(ert-deftest ruby-indent-after-block-in-continued-expression ()
 +  (ruby-should-indent-buffer
 +   "var =
 +   |  begin
 +   |    val
 +   |  end
 +   |statement"
 +   "var =
 +   |begin
 +   |val
 +   |end
 +   |statement"))
 +
 +(ert-deftest ruby-indent-spread-args-in-parens ()
 +  (let ((ruby-deep-indent-paren '(?\()))
 +    (ruby-should-indent-buffer
 +     "foo(1,
 +     |    2,
 +     |    3)
 +     |"
 +     "foo(1,
 +     | 2,
 +     |  3)
 +     |")))
 +
 +(ert-deftest ruby-align-to-stmt-keywords-t ()
 +  (let ((ruby-align-to-stmt-keywords t))
 +    (ruby-should-indent-buffer
 +     "foo = if bar?
 +     |  1
 +     |else
 +     |  2
 +     |end
 +     |
 +     |foo || begin
 +     |  bar
 +     |end
 +     |
 +     |foo ||
 +     |  begin
 +     |    bar
 +     |  end
 +     |"
 +     "foo = if bar?
 +     |       1
 +     |else
 +     |  2
 +     | end
 +     |
 +     | foo || begin
 +     |    bar
 +     |end
 +     |
 +     |  foo ||
 +     | begin
 +     |bar
 +     |  end
 +     |")
 +    ))
 +
 +(ert-deftest ruby-align-to-stmt-keywords-case ()
 +  (let ((ruby-align-to-stmt-keywords '(case)))
 +    (ruby-should-indent-buffer
 +     "b = case a
 +     |when 13
 +     |  6
 +     |else
 +     |  42
 +     |end"
 +     "b = case a
 +     |    when 13
 +     |  6
 +     |    else
 +     |      42
 +     |    end")))
 +
 +(ert-deftest ruby-align-chained-calls ()
 +  (let ((ruby-align-chained-calls t))
 +    (ruby-should-indent-buffer
 +     "one.two.three
 +     |       .four
 +     |
 +     |my_array.select { |str| str.size > 5 }
 +     |        .map    { |str| str.downcase }"
 +     "one.two.three
 +     |  .four
 +     |
 +     |my_array.select { |str| str.size > 5 }
 +     |   .map    { |str| str.downcase }")))
 +
 +(ert-deftest ruby-move-to-block-stops-at-indentation ()
 +  (ruby-with-temp-buffer "def f\nend"
 +    (beginning-of-line)
 +    (ruby-move-to-block -1)
 +    (should (looking-at "^def"))))
 +
 +(ert-deftest ruby-toggle-block-to-do-end ()
 +  (ruby-with-temp-buffer "foo {|b|\n}"
 +    (beginning-of-line)
 +    (ruby-toggle-block)
 +    (should (string= "foo do |b|\nend" (buffer-string)))))
 +
 +(ert-deftest ruby-toggle-block-to-brace ()
 +  (let ((pairs '((17 . "foo { |b| b + 2 }")
 +                 (16 . "foo { |b|\n  b + 2\n}"))))
 +    (dolist (pair pairs)
 +      (with-temp-buffer
 +        (let ((fill-column (car pair)))
 +          (insert "foo do |b|\n  b + 2\nend")
 +          (ruby-mode)
 +          (beginning-of-line)
 +          (ruby-toggle-block)
 +          (should (string= (cdr pair) (buffer-string))))))))
 +
 +(ert-deftest ruby-toggle-block-to-multiline ()
 +  (ruby-with-temp-buffer "foo {|b| b + 1}"
 +    (beginning-of-line)
 +    (ruby-toggle-block)
 +    (should (string= "foo do |b|\n  b + 1\nend" (buffer-string)))))
 +
 +(ert-deftest ruby-toggle-block-with-interpolation ()
 +  (ruby-with-temp-buffer "foo do\n  \"#{bar}\"\nend"
 +    (beginning-of-line)
 +    (ruby-toggle-block)
 +    (should (string= "foo { \"#{bar}\" }" (buffer-string)))))
 +
 +(ert-deftest ruby-recognize-symbols-starting-with-at-character ()
 +  (ruby-assert-face ":@abc" 3 font-lock-constant-face))
 +
 +(ert-deftest ruby-hash-character-not-interpolation ()
 +  (ruby-assert-face "\"This is #{interpolation}\"" 15
 +                    font-lock-variable-name-face)
 +  (ruby-assert-face "\"This is \\#{no interpolation} despite the #\""
 +                    15 font-lock-string-face)
 +  (ruby-assert-face "\n#@comment, not ruby code" 5 font-lock-comment-face)
 +  (ruby-assert-state "\n#@comment, not ruby code" 4 t)
 +  (ruby-assert-face "# A comment cannot have #{an interpolation} in it"
 +                    30 font-lock-comment-face)
 +  (ruby-assert-face "# #{comment}\n \"#{interpolation}\"" 16
 +                    font-lock-variable-name-face))
 +
 +(ert-deftest ruby-interpolation-suppresses-quotes-inside ()
 +  (let ((s "\"<ul><li>#{@files.join(\"</li><li>\")}</li></ul>\""))
 +    (ruby-assert-state s 8 nil)
 +    (ruby-assert-face s 9 font-lock-string-face)
 +    (ruby-assert-face s 10 font-lock-variable-name-face)
 +    (ruby-assert-face s 41 font-lock-string-face)))
 +
 +(ert-deftest ruby-interpolation-suppresses-one-double-quote ()
 +  (let ((s "\"foo#{'\"'}\""))
 +    (ruby-assert-state s 8 nil)
 +    (ruby-assert-face s 8 font-lock-variable-name-face)
 +    (ruby-assert-face s 11 font-lock-string-face)))
 +
 +(ert-deftest ruby-interpolation-suppresses-one-backtick ()
 +  (let ((s "`as#{'`'}das`"))
 +    (ruby-assert-state s 8 nil)))
 +
 +(ert-deftest ruby-interpolation-keeps-non-quote-syntax ()
 +  (let ((s "\"foo#{baz.tee}bar\""))
 +    (ruby-with-temp-buffer s
 +      (goto-char (point-min))
 +      (ruby-mode)
 +      (syntax-propertize (point-max))
 +      (search-forward "tee")
 +      (should (string= (thing-at-point 'symbol) "tee")))))
 +
 +(ert-deftest ruby-interpolation-inside-percent-literal ()
 +  (let ((s "%( #{boo} )"))
 +    (ruby-assert-face s 1 font-lock-string-face)
 +    (ruby-assert-face s 4 font-lock-variable-name-face)
 +    (ruby-assert-face s 10 font-lock-string-face)
 +    (ruby-assert-state s 8 nil)))
 +
 +(ert-deftest ruby-interpolation-inside-percent-literal-with-paren ()
 +  :expected-result :failed
 +  (let ((s "%(^#{\")\"}^)"))
 +    (ruby-assert-face s 3 font-lock-string-face)
 +    (ruby-assert-face s 4 font-lock-variable-name-face)
 +    (ruby-assert-face s 10 font-lock-string-face)
 +    ;; It's confused by the closing paren in the middle.
 +    (ruby-assert-state s 8 nil)))
 +
++(ert-deftest ruby-interpolation-inside-another-interpolation ()
++  :expected-result :failed
++  (let ((s "\"#{[a, b, c].map { |v| \"#{v}\" }.join}\""))
++    (ruby-assert-face s 1 font-lock-string-face)
++    (ruby-assert-face s 2 font-lock-variable-name-face)
++    (ruby-assert-face s 38 font-lock-string-face)
++    (ruby-assert-state s 8 nil)))
++
 +(ert-deftest ruby-interpolation-inside-double-quoted-percent-literals ()
 +  (ruby-assert-face "%Q{foo #@bar}" 8 font-lock-variable-name-face)
 +  (ruby-assert-face "%W{foo #@bar}" 8 font-lock-variable-name-face)
 +  (ruby-assert-face "%r{foo #@bar}" 8 font-lock-variable-name-face)
 +  (ruby-assert-face "%x{foo #@bar}" 8 font-lock-variable-name-face))
 +
 +(ert-deftest ruby-no-interpolation-in-single-quoted-literals ()
 +  (ruby-assert-face "'foo #@bar'" 7 font-lock-string-face)
 +  (ruby-assert-face "%q{foo #@bar}" 8 font-lock-string-face)
 +  (ruby-assert-face "%w{foo #@bar}" 8 font-lock-string-face)
 +  (ruby-assert-face "%s{foo #@bar}" 8 font-lock-string-face))
 +
 +(ert-deftest ruby-interpolation-after-dollar-sign ()
 +  (ruby-assert-face "\"$#{balance}\"" 2 'font-lock-string-face)
 +  (ruby-assert-face "\"$#{balance}\"" 3 'font-lock-variable-name-face))
 +
 +(ert-deftest ruby-no-unknown-percent-literals ()
 +  ;; No folding of case.
 +  (ruby-assert-face "%S{foo}" 4 nil)
 +  (ruby-assert-face "%R{foo}" 4 nil))
 +
 +(ert-deftest ruby-no-nested-percent-literals ()
 +  (ruby-with-temp-buffer "a = %w[b %()]"
 +    (syntax-propertize (point))
 +    (should (null (nth 8 (syntax-ppss))))
 +    (should (eq t (nth 3 (syntax-ppss (1- (point-max))))))
 +    (search-backward "[")
 +    (should (eq t (nth 3 (syntax-ppss))))))
 +
 +(ert-deftest ruby-add-log-current-method-examples ()
 +  (let ((pairs '(("foo" . "#foo")
 +                 ("C.foo" . ".foo")
 +                 ("self.foo" . ".foo"))))
 +    (dolist (pair pairs)
 +      (let ((name  (car pair))
 +            (value (cdr pair)))
 +        (ruby-with-temp-buffer (ruby-test-string
 +                                "module M
 +                                |  class C
 +                                |    def %s
 +                                |      _
 +                                |    end
 +                                |  end
 +                                |end"
 +                                name)
 +          (search-backward "_")
 +          (forward-line)
 +          (should (string= (ruby-add-log-current-method)
 +                           (format "M::C%s" value))))))))
 +
 +(ert-deftest ruby-add-log-current-method-outside-of-method ()
 +  (ruby-with-temp-buffer (ruby-test-string
 +                          "module M
 +                          |  class C
 +                          |    def foo
 +                          |    end
 +                          |    _
 +                          |  end
 +                          |end")
 +    (search-backward "_")
 +    (should (string= (ruby-add-log-current-method)"M::C"))))
 +
 +(ert-deftest ruby-add-log-current-method-in-singleton-class ()
 +  (ruby-with-temp-buffer (ruby-test-string
 +                          "class C
 +                          |  class << self
 +                          |    def foo
 +                          |      _
 +                          |    end
 +                          |  end
 +                          |end")
 +    (search-backward "_")
 +    (should (string= (ruby-add-log-current-method) "C.foo"))))
 +
 +(ert-deftest ruby-add-log-current-method-namespace-shorthand ()
 +  (ruby-with-temp-buffer (ruby-test-string
 +                          "class C::D
 +                          |  def foo
 +                          |    _
 +                          |  end
 +                          |end")
 +    (search-backward "_")
 +    (should (string= (ruby-add-log-current-method) "C::D#foo"))))
 +
 +(ert-deftest ruby-add-log-current-method-after-inner-class ()
 +  (ruby-with-temp-buffer (ruby-test-string
 +                          "module M
 +                          |  class C
 +                          |    class D
 +                          |    end
 +                          |    def foo
 +                          |      _
 +                          |    end
 +                          |  end
 +                          |end")
 +    (search-backward "_")
 +    (should (string= (ruby-add-log-current-method) "M::C#foo"))))
 +
 +(defvar ruby-block-test-example
 +  (ruby-test-string
 +   "class C
 +   |  def foo
 +   |    1
 +   |  end
 +   |
 +   |  def bar
 +   |    2
 +   |  end
 +   |
 +   |  def baz
 +   |some do
 +   |3
 +   |    end
 +   |  end
 +   |end"))
 +
 +(defmacro ruby-deftest-move-to-block (name &rest body)
 +  (declare (indent defun))
 +  `(ert-deftest ,(intern (format "ruby-move-to-block-%s" name)) ()
 +     (with-temp-buffer
 +       (insert ruby-block-test-example)
 +       (ruby-mode)
 +       (goto-char (point-min))
 +       ,@body)))
 +
 +(ruby-deftest-move-to-block works-on-do
 +  (forward-line 10)
 +  (ruby-end-of-block)
 +  (should (= 13 (line-number-at-pos)))
 +  (ruby-beginning-of-block)
 +  (should (= 11 (line-number-at-pos))))
 +
 +(ruby-deftest-move-to-block zero-is-noop
 +  (forward-line 4)
 +  (ruby-move-to-block 0)
 +  (should (= 5 (line-number-at-pos))))
 +
 +(ruby-deftest-move-to-block ok-with-three
 +  (forward-line 1)
 +  (ruby-move-to-block 3)
 +  (should (= 14 (line-number-at-pos))))
 +
 +(ruby-deftest-move-to-block ok-with-minus-two
 +  (forward-line 9)
 +  (ruby-move-to-block -2)
 +  (should (= 2 (line-number-at-pos))))
 +
 +(ert-deftest ruby-move-to-block-skips-percent-literal ()
 +  (dolist (s (list (ruby-test-string
 +                    "foo do
 +                    |  a = %%w(
 +                    |    def yaa
 +                    |  )
 +                    |end")
 +                   (ruby-test-string
 +                    "foo do
 +                    |  a = %%w|
 +                    |    end
 +                    |  |
 +                    |end")))
 +    (ruby-with-temp-buffer s
 +      (goto-char (point-min))
 +      (ruby-end-of-block)
 +      (should (= 5 (line-number-at-pos)))
 +      (ruby-beginning-of-block)
 +      (should (= 1 (line-number-at-pos))))))
 +
 +(ert-deftest ruby-move-to-block-skips-heredoc ()
 +  (ruby-with-temp-buffer
 +      (ruby-test-string
 +       "if something_wrong?
 +       |  ActiveSupport::Deprecation.warn(<<-eowarn)
 +       |  boo hoo
 +       |  end
 +       |  eowarn
 +       |end")
 +    (goto-char (point-min))
 +    (ruby-end-of-block)
 +    (should (= 6 (line-number-at-pos)))
 +    (ruby-beginning-of-block)
 +    (should (= 1 (line-number-at-pos)))))
 +
 +(ert-deftest ruby-move-to-block-does-not-fold-case ()
 +  (ruby-with-temp-buffer
 +      (ruby-test-string
 +       "foo do
 +       |  Module.to_s
 +       |end")
 +    (let ((case-fold-search t))
 +      (ruby-beginning-of-block))
 +    (should (= 1 (line-number-at-pos)))))
 +
 +(ert-deftest ruby-move-to-block-moves-from-else-to-if ()
 +  (ruby-with-temp-buffer (ruby-test-string
 +                          "if true
 +                          |  nested_block do
 +                          |  end
 +                          |else
 +                          |end")
 +    (goto-char (point-min))
 +    (forward-line 3)
 +    (ruby-beginning-of-block)
 +    (should (= 1 (line-number-at-pos)))))
 +
 +(ert-deftest ruby-beginning-of-defun-does-not-fold-case ()
 +  (ruby-with-temp-buffer
 +      (ruby-test-string
 +       "class C
 +       |  def bar
 +       |    Class.to_s
 +       |  end
 +       |end")
 +    (goto-char (point-min))
 +    (forward-line 3)
 +    (let ((case-fold-search t))
 +      (beginning-of-defun))
 +    (should (= 2 (line-number-at-pos)))))
 +
 +(ert-deftest ruby-end-of-defun-skips-to-next-line-after-the-method ()
 +  (ruby-with-temp-buffer
 +      (ruby-test-string
 +       "class D
 +       |  def tee
 +       |    'ho hum'
 +       |  end
 +       |end")
 +    (goto-char (point-min))
 +    (forward-line 1)
 +    (end-of-defun)
 +    (should (= 5 (line-number-at-pos)))))
 +
 +(defvar ruby-sexp-test-example
 +  (ruby-test-string
 +   "class C
 +   |  def foo
 +   |    self.end
 +   |    D.new.class
 +   |    [1, 2, 3].map do |i|
 +   |      i + 1
 +   |    end.sum
 +   |  end
 +   |end"))
 +
 +(ert-deftest ruby-forward-sexp-skips-method-calls-with-keyword-names ()
 +  (ruby-with-temp-buffer ruby-sexp-test-example
 +    (goto-line 2)
 +    (ruby-forward-sexp)
 +    (should (= 8 (line-number-at-pos)))))
 +
 +(ert-deftest ruby-backward-sexp-skips-method-calls-with-keyword-names ()
 +  (ruby-with-temp-buffer ruby-sexp-test-example
 +    (goto-line 8)
 +    (end-of-line)
 +    (ruby-backward-sexp)
 +    (should (= 2 (line-number-at-pos)))))
 +
 +(ert-deftest ruby--insert-coding-comment-ruby-style ()
 +  (with-temp-buffer
 +    (let ((ruby-encoding-magic-comment-style 'ruby))
 +      (ruby--insert-coding-comment "utf-8")
 +      (should (string= "# coding: utf-8\n" (buffer-string))))))
 +
 +(ert-deftest ruby--insert-coding-comment-emacs-style ()
 +  (with-temp-buffer
 +    (let ((ruby-encoding-magic-comment-style 'emacs))
 +      (ruby--insert-coding-comment "utf-8")
 +      (should (string= "# -*- coding: utf-8 -*-\n" (buffer-string))))))
 +
 +(ert-deftest ruby--insert-coding-comment-custom-style ()
 +  (with-temp-buffer
 +    (let ((ruby-encoding-magic-comment-style 'custom)
 +          (ruby-custom-encoding-magic-comment-template "# encoding: %s\n"))
 +      (ruby--insert-coding-comment "utf-8")
 +      (should (string= "# encoding: utf-8\n\n" (buffer-string))))))
 +
 +
 +(provide 'ruby-mode-tests)
 +
 +;;; ruby-mode-tests.el ends here
index 585263d02a6c713ff076079947d21b3f20ae43b4,0000000000000000000000000000000000000000..b038512b114cf0e0d58a0301519590a19ddda9b9
mode 100644,000000..100644
--- /dev/null
@@@ -1,433 -1,0 +1,477 @@@
- "abc/#{def}ghi"
- "abc\#{def}ghi"
 +if something_wrong?             # ruby-move-to-block-skips-heredoc
 +  ActiveSupport::Deprecation.warn(<<-eowarn)
 +  boo hoo
 +  end
 +  eowarn
 +  foo
 +
 +  foo(<<~squiggly)
 +  end
 +  squiggly
 +end
 +
 +def foo
 +  %^bar^
 +end
 +
 +# Percent literals.
 +b = %Q{This is a "string"}
 +c = %w!foo
 + bar
 + baz!
 +d = %(hello (nested) world)
 +
 +# Don't propertize percent literals inside strings.
 +"(%s, %s)" % [123, 456]
 +
- foo
++"abc/#{ddf}ghi"
++"abc\#{ddf}ghi"
 +
 +# Or inside comments.
 +x = # "tot %q/to"; =
 +  y = 2 / 3
 +
 +# Regexp after whitelisted method.
 +"abc".sub /b/, 'd'
 +
 +# Don't mis-match "sub" at the end of words.
 +a = asub / aslb + bsub / bslb;
 +
 +# Highlight the regexp after "if".
 +x = toto / foo if /do bar/ =~ "dobar"
 +
 +# Regexp options are highlighted.
 +
 +/foo/xi != %r{bar}mo.tee
 +
 +foo { /"tee/
 +  bar { |qux| /'fee"/ }         # bug#20026
 +}
 +
 +bar(class: XXX) do              # ruby-indent-keyword-label
 +  foo
 +end
 +bar
 +
 +foo = [1,                       # ruby-deep-indent
 +       2]
 +
 +foo = {                         # ruby-deep-indent-disabled
 +  a: b
 +}
 +
 +foo = { a: b,
 +        a1: b1
 +      }
 +
 +foo({                           # bug#16118
 +      a: b,
 +      c: d
 +    })
 +
 +bar = foo(
 +  a, [
 +    1,
 +  ],
 +  :qux => [
 +    3
 +  ])
 +
 +foo(
 +  [
 +    {
 +      a: b
 +    },
 +  ],
 +  {
 +    c: d
 +  }
 +)
 +
 +foo([{
 +       a: 2
 +     },
 +     {
 +       b: 3
 +     },
 +     4
 +    ])
 +
 +foo = [                         # ruby-deep-indent-disabled
 +  1
 +]
 +
 +foo(                            # ruby-deep-indent-disabled
 +  a
 +)
 +
 +# Multiline regexp.
 +/bars
 + tees # toots
 + nfoos/
 +
 +def test1(arg)
 +  puts "hello"
 +end
 +
 +def test2 (arg)
 +  a = "apple"
 +
 +  if a == 2
 +    puts "hello"
 +  else
 +    puts "there"
 +  end
 +
 +  if a == 2 then
 +    puts "hello"
 +  elsif a == 3
 +    puts "hello3"
 +  elsif a == 3 then
 +    puts "hello3"
 +  else
 +    puts "there"
 +  end
 +
 +  b = case a
 +      when "a"
 +        6
 +      # Support for this syntax was removed in Ruby 1.9, so we
 +      # probably don't need to handle it either.
 +      # when "b" :
 +      #   7
 +      # when "c" : 2
 +      when "d"  then 4
 +      else 5
 +      end
 +end
 +
 +# Some Cucumber code:
 +Given /toto/ do
 +  print "hello"
 +end
 +
 +# Bug#15208
 +if something == :==
 +  do_something
 +
 +  return false unless method == :+
 +  x = y + z # Bug#16609
 +
 +  a = 1 ? 2 :(
 +    2 + 3
 +  )
 +end
 +
 +# Bug#17097
 +if x == :!=
 +  something
 +end
 +
 +qux :+,
 +    bar,
 +    :[]=,
 +    bar,
 +    :a
 +
 +b = $:
 +c = ??
 +
 +# Example from http://www.ruby-doc.org/docs/ProgrammingRuby/html/language.html
 +d = 4 + 5 +      # no '\' needed
 +    6 + 7
 +
 +# Example from http://www.ruby-doc.org/docs/ProgrammingRuby/html/language.html
 +e = 8 + 9   \
 +    + 10         # '\' needed
 +
 +foo = obj.bar { |m| tee(m) } +
 +      obj.qux { |m| hum(m) }
 +
 +begin
 +  foo
 +ensure
 +  bar
 +end
 +
 +# Bug#15369
 +MSG = 'Separate every 3 digits in the integer portion of a number' \
 +      'with underscores(_).'
 +
 +class C
 +  def foo
 +    self.end
 +    D.new.class
 +  end
 +
 +  def begin
 +  end
 +end
 +
 +a = foo(j, k) -
 +    bar_tee
 +
 +while a < b do # "do" is optional
 +  foo
 +end
 +
 +desc "foo foo" \
 +     "bar bar"
 +
 +foo.
 +  bar
 +
 +# https://github.com/rails/rails/blob/17f5d8e062909f1fcae25351834d8e89967b645e/activesupport/lib/active_support/time_with_zone.rb#L206
-   foo == bar and
++foo # comment intended to confuse the tokenizer
 +  .bar
 +
 +z = {
 +  foo: {
 +    a: "aaa",
 +    b: "bbb"
 +  }
 +}
 +
 +foo if
 +  bar
 +
 +fail "stuff" \
 +  unless all_fine?
 +
 +if foo?
 +  bar
 +end
 +
 +method arg1,                   # bug#15594
 +       method2 arg2,
 +               arg3
 +
 +method? arg1,
 +        arg2
 +
 +method! arg1,
 +        arg2
 +
 +method !arg1,
 +       arg2
 +
 +method [],
 +       arg2
 +
 +method :foo,
 +       :bar
 +
 +method (a + b),
 +       c, :d => :e,
 +       f: g
 +
 +desc "abc",
 +     defg
 +
 +it "is a method call with block" do |asd|
 +  foo
 +end
 +
 +it("is too!") {
 +  bar
 +    .qux
 +}
 +
 +and_this_one(has) { |block, parameters|
 +  tee
 +}
 +
 +if foo &&
 +   bar
 +end
 +
 +foo +
 +  bar
 +
 +foo and
 +  bar
 +
 +foo > bar &&
 +  tee < qux
 +
 +zux do
-   .qux.bar
-   .tee
++  foo == bar &&
 +    tee == qux
++
++  a = 3 and
++    b = 4
 +end
 +
++foo + bar ==
++  tee + qux
++
++1 .. 2 &&
++     3
++
++3 < 4 +
++    5
++
++10 << 4 ^
++  20
++
++100 + 2 >>
++  3
++
++2 ** 10 /
++  2
++
 +foo ^
 +  bar
 +
 +foo_bar_tee(1, 2, 3)
++  .qux&.bar
++  .tee.bar
++  &.tee
 +
 +foo do
 +  bar
 +    .tee
 +end
 +
 +def bar
 +  foo
 +    .baz
 +end
 +
++abc(foo
++      .bar,
++    tee
++      .qux)
++
 +# http://stackoverflow.com/questions/17786563/emacs-ruby-mode-if-expressions-indentation
 +tee = if foo
 +        bar
 +      else
 +        tee
 +      end
 +
 +a = b {
 +  c
 +}
 +
 +aa = bb do
 +  cc
 +end
 +
 +foo :bar do
 +  qux
 +end
 +
 +foo do |*args|
 +  tee
 +end
 +
 +bar do |&block|
 +  tee
 +end
 +
 +foo = [1, 2, 3].map do |i|
 +  i + 1
 +end
 +
 +bar.foo do
 +  bar
 +end
 +
 +bar.foo(tee) do
 +  bar
 +end
 +
 +bar.foo(tee) {
 +  bar
 +}
 +
 +bar 1 do
 +  foo 2 do
 +    tee
 +  end
 +end
 +
 +foo |
 +  bar
 +
 +def qux
 +  foo ||= begin
 +            bar
 +            tee
 +          rescue
 +            oomph
 +          end
 +end
 +
 +private def foo
 +  bar
 +end
 +
 +%^abc^
 +ddd
 +
 +qux = foo.fee ?
 +        bar :
 +        tee
 +
 +zoo.keep.bar!(
 +  {x: y,
 +   z: t})
 +
 +zoo
 +  .lose(
 +    q, p)
 +
 +a.records().map(&:b).zip(
 +  foo)
 +
++foo1 =
++  subject.update(
++    1
++  )
++
++foo2 =
++  subject.
++    update(
++      2
++    )
++
 +# FIXME: This is not consistent with the example below it, but this
 +# offset only happens if the colon is at eol, which wouldn't be often.
 +# Tokenizing `bar:' as `:bar =>' would be better, but it's hard to
 +# distinguish from a variable reference inside a ternary operator.
 +foo(bar:
 +      tee)
 +
 +foo(:bar =>
 +    tee)
 +
++regions = foo(
++  OpenStruct.new(id: 0, name: "foo") => [
++    10
++  ]
++)
++
 +{'a' => {
 +   'b' => 'c',
 +   'd' => %w(e f)
 + }
 +}
 +
 +# Bug#17050
 +
 +return render json: {
 +                errors: { base: [message] },
 +                copying: copying
 +              },
 +              status: 400
 +
 +top test(
 +      some,
 +      top,
 +      test)
 +
 +foo bar, {
 +      tee: qux
 +    }