[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master 1b76d91 5/5: -
From: |
John Wiegley |
Subject: |
[Emacs-diffs] master 1b76d91 5/5: - |
Date: |
Tue, 19 Jan 2016 07:18:10 +0000 |
branch: master
commit 1b76d9168336ede8976b980aeaed64ae2908501a
Merge: bca4930 2e5a89f
Author: John Wiegley <address@hidden>
Commit: John Wiegley <address@hidden>
-
---
INSTALL | 3 +
configure.ac | 1 -
doc/emacs/maintaining.texi | 180 ++++++++++++++++++------------------
doc/emacs/programs.texi | 4 +-
doc/emacs/search.texi | 8 +-
doc/lispref/commands.texi | 8 ++
doc/lispref/frames.texi | 49 ++++++----
doc/lispref/functions.texi | 119 ++++++++++++++++++++++--
doc/lispref/lists.texi | 8 ++
doc/lispref/loading.texi | 18 ++--
doc/lispref/macros.texi | 6 +
doc/lispref/strings.texi | 8 ++-
doc/lispref/symbols.texi | 17 +++-
etc/NEWS | 37 ++++++--
lisp/desktop.el | 151 ++++++++++++++++++++----------
lisp/dired-aux.el | 35 +++++++
lisp/dired.el | 4 +-
lisp/emacs-lisp/inline.el | 2 +-
lisp/net/shr.el | 4 +-
lisp/progmodes/project.el | 5 +-
lisp/progmodes/ruby-mode.el | 9 ++-
lisp/progmodes/xref.el | 65 +++++++++-----
m4/ax_gcc_var_attribute.m4 | 141 ----------------------------
src/conf_post.h | 26 +++--
src/emacs-module.c | 3 +-
src/fns.c | 3 +-
src/gnutls.c | 10 +-
src/gnutls.h | 1 +
src/sysdep.c | 66 +++++++++----
src/window.c | 64 +++++++++----
test/manual/etags/CTAGS.good | 14 ++--
test/manual/etags/ETAGS.good_1 | 14 ++--
test/manual/etags/ETAGS.good_2 | 14 ++--
test/manual/etags/ETAGS.good_3 | 14 ++--
test/manual/etags/ETAGS.good_4 | 14 ++--
test/manual/etags/ETAGS.good_5 | 14 ++--
test/manual/etags/ETAGS.good_6 | 14 ++--
test/manual/etags/ruby-src/test.rb | 34 ++++---
38 files changed, 704 insertions(+), 483 deletions(-)
diff --git a/INSTALL b/INSTALL
index 37ba9d9..6f516bd 100644
--- a/INSTALL
+++ b/INSTALL
@@ -311,6 +311,9 @@ typical 32-bit host, Emacs integers have 62 bits instead of
30.
Use --with-cairo to compile Emacs with Cairo drawing.
+Use --with-modules to build Emacs with support for loading dynamic
+modules.
+
Use --enable-gcc-warnings to enable compile-time checks that warn
about possibly-questionable C code. This is intended for developers
and is useful with GNU-compatible compilers. On a recent GNU system
diff --git a/configure.ac b/configure.ac
index ddf0f5f..d3b5183 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3350,7 +3350,6 @@ if test "${HAVE_MODULES}" = yes; then
fi
AC_SUBST(MODULES_OBJ)
AC_SUBST(LIBMODULES)
-AX_GCC_VAR_ATTRIBUTE(cleanup)
AC_CHECK_FUNCS(dladdr)
### Use -lpng if available, unless '--with-png=no'.
diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi
index 8842b8e..989d8ff 100644
--- a/doc/emacs/maintaining.texi
+++ b/doc/emacs/maintaining.texi
@@ -1686,19 +1686,38 @@ permitted provided the copyright notice and this notice
are preserved.
Of course, you should substitute the proper years and copyright holder.
@node Xref
address@hidden Find Identifier Definitions and References
address@hidden Find Identifier References
@cindex xref
- An @dfn{identifier} is a syntactic elements of the program: a
-function, a subroutine, a method, a class, a data type, a macro, etc.
-In a programming language, each identifier is a symbol in the
-language's syntax. Many program development tools provide
-capabilities to extract references to identifiers from source files,
-record them on specialized data bases, and then use those data bases
-to quickly find where each identifier was defined and referenced.
+ An @dfn{identifier} is a name of a syntactical subunit of the
+program: a function, a subroutine, a method, a class, a data type, a
+macro, etc. In a programming language, each identifier is a symbol in
+the language's syntax. Program development and maintenance requires
+capabilities to quickly find where each identifier was defined and
+referenced, to rename identifiers across the entire project, etc.
-Emacs provides a unified user interface to these tools, called
address@hidden The tools supported by @samp{xref} include:
+These capabilities are also useful for finding references in major
+modes other than those defined to support programming languages. For
+example, chapters, sections, appendices, etc.@: of a text or a @TeX{}
+document can be treated as subunits as well, and their names can be
+used as identifiers. In this chapter, we use the term ``identifiers''
+to collectively refer to the names of any kind of subunits, in program
+source and in other kinds of text alike.
+
+Emacs provides a unified interface to these capabilities, called
address@hidden
+
address@hidden xref backend
+To do its job, @code{xref} needs to make use of information and to
+employ methods specific to the major mode. What files to search for
+identifiers, how to find references to identifiers, how to complete on
+identifiers---all this and more is mode-specific knowledge.
address@hidden delegates the mode-specific parts of its job to a
address@hidden provided by the mode; it also includes defaults for some
+of its commands, for those modes that don't provide their own.
+
+A backend can implement its capabilities in a variety of ways. Here
+are a few examples:
@enumerate a
@item
@@ -1706,49 +1725,25 @@ Some major modes provide built-in means for looking up
the language
symbols. For example, Emacs Lisp symbols can be identified by
searching the package load history, maintained by the Emacs Lisp
interpreter, and by consulting the built-in documentation strings; the
-Emacs Lisp mode uses these facilities to find definitions of symbols.
-
address@hidden
-Etags, the command for tagging identifier definitions which is part of
-the Emacs distribution. @xref{Create Tags Table}.
-
address@hidden
address@hidden GLOBAL, the source code tagging system, which provides
-the @command{gtags} command and associated utilities. @xref{Command
-Line, gtags, , global, GNU GLOBAL source code tag system}.
+Emacs Lisp mode uses these facilities in its backend to allow finding
+definitions of symbols. (One disadvantage of this kind of backend is
+that it only knows about subunits that were loaded into the
+interpreter.)
@item
-Cscope (@uref{http://cscope.sourceforge.net/}, a tool for browsing
-source code.
-
address@hidden
address@hidden IDUtils, a package for generating databases of
-identifier references and querying those databases. @xref{Top,,,
-idutils, ID database utilities}.
-
address@hidden
-Grep, the venerable program that searches files for lines matching
-patterns. @xref{Invoking,,, grep, GNU Grep Manual}.
+An external program can extract references by scanning the relevant
+files, and build a database of these references. A backend can then
+access this database whenever it needs to list or look up references.
+The Emacs distribution includes @command{etags}, a command for tagging
+identifier definitions in programs, which supports many programming
+languages and other major modes, such as HTML, by extracting
+references into @dfn{tags tables}. @xref{Create Tags Table}. Major
+modes for languages supported by @command{etags} can use tags tables
+as basis for their backend. (One disadvantage of this kind of backend
+is that tags tables need to be kept reasonably up to date, by
+rebuilding them from time to time.)
@end enumerate
address@hidden
-Additional tools could be supported as they become available, or as
-user extensions. Each such tool is used as a @dfn{backend} by
-commands described in this section. Each command detects which
-backends are available for the current major mode, and uses the most
-capable of the available backends, with Grep generally serving as the
-fall-back backend.
-
address@hidden tag
-The commands described here are useful for finding references in major
-modes other than those defined to support programming languages. For
-example, chapters, sections, appendices, etc. of a text or a @TeX{}
-document can be treated as identifiers as well. In this chapter, we
-collectively refer to a reference that specifies the name of the file
-where the corresponding subunit is defined, and the position of the
-subunit's definition in that file, as a @dfn{tag}. We refer to the
-backends used by @code{xref} as @dfn{tagging backends}.
-
@menu
* Find Identifiers:: Commands to find where an identifier is defined
or referenced, to list identifiers, etc.
@@ -1759,14 +1754,16 @@ backends used by @code{xref} as @dfn{tagging backends}.
@node Find Identifiers
@subsection Find Identifiers
- This subsection describes the commands that use the tagging backends
-in order to find definitions of identifiers, references to
-identifiers, and perform various queries about identifiers. With most
-backends, these definitions and references were recorded as tags in
-the database created and maintained by the backend.
+ This subsection describes the commands that find references to
+identifiers and perform various queries about identifiers. Each such
+reference could @emph{define} an identifier, e.g., provide the
+implementation of a program subunit or the text of a document section;
+or it could @emph{use} the identifier, e.g., call a function or a
+method, assign a value to a variable, mention a chapter in a
+cross-reference, etc.
@menu
-* Looking Up Identifiers:: Commands to find the definition of a specific tag.
+* Looking Up Identifiers:: Commands to find the definition of an identifier.
* Xref Commands:: Commands in the @file{*xref*} buffer.
* Identifier Search:: Searching and replacing identifiers.
* List Identifiers:: Listing identifiers and completing on them.
@@ -1794,7 +1791,7 @@ Find definitions of identifier, but display it in another
window
Find definition of identifier, and display it in a new frame
(@code{xref-find-definitions-other-frame}).
@item M-,
-Pop back to where you previously invoked @kbd{M-.} and friends
+Go back to where you previously invoked @kbd{M-.} and friends
(@code{xref-pop-marker-stack}).
@end table
@@ -1832,7 +1829,8 @@ former is @address@hidden 4 .}}
The command @kbd{C-M-.} (@code{xref-find-apropos}) finds the
definitions of one or more identifiers that match a specified regular
expression. It is just like @kbd{M-.} except that it does regexp
-matching of identifiers instead of symbol name matching.
+matching of identifiers instead of matching symbol names as fixed
+strings.
When any of the above commands finds more than one definition, it
presents the @file{*xref*} buffer showing the definition candidates.
@@ -1896,13 +1894,9 @@ without displaying the references.
@cindex search and replace in multiple files
@cindex multiple-file search and replace
- The commands in this section visit and search all the files listed
-in the @code{xref} backend's database, one by one. For these
-commands, the database serves only to specify a sequence of files to
-search. These commands scan all the databases starting with the first
-one (if any) that describes the current file, proceed from there to
-the end of the list, and then scan from the beginning of the list
-until they have covered all the databases in the list.
+ The commands in this section perform various search and replace
+operations either on identifiers themselves or on files that reference
+them.
@table @kbd
@item M-?
@@ -1931,7 +1925,7 @@ referenced. The XREF mode commands are available in this
buffer, see
@findex xref-query-replace
@kbd{M-x xref-query-replace} reads a regexp to match identifier
-names and a string to replace with, just like ordinary @kbd{M-x
+names and a replacement string, just like ordinary @kbd{M-x
query-replace-regexp}. It then performs the specified replacement in
the names of the matching identifiers in all the places in all the
files where these identifiers are referenced. This is useful when you
@@ -1943,15 +1937,14 @@ be invoked in the @file{*xref*} buffer generated by
@code{M-?}.
searches for matches in all the files in the selected tags table, one
file at a time. It displays the name of the file being searched so
you can follow its progress. As soon as it finds an occurrence,
address@hidden returns. This command works only with the etags
-backend, and requires tags tables to be available (@pxref{Tags
-Tables}).
address@hidden returns. This command requires tags tables to be
+available (@pxref{Tags Tables}).
@findex tags-loop-continue
- Having found one match, you probably want to find all the rest.
-Type @kbd{M-x tags-loop-continue}) to resume the @code{tags-search},
-finding one more match. This searches the rest of the current buffer,
-followed by the remaining files of the tags table.
+ Having found one match with @code{tags-search}, you probably want to
+find all the rest. Type @kbd{M-x tags-loop-continue} to resume the
address@hidden, finding one more match. This searches the rest of
+the current buffer, followed by the remaining files of the tags table.
@findex tags-query-replace
@kbd{M-x tags-query-replace} performs a single
@@ -1960,7 +1953,6 @@ reads a regexp to search for and a string to replace
with, just like
ordinary @kbd{M-x query-replace-regexp}. It searches much like @kbd{M-x
tags-search}, but repeatedly, processing matches according to your
input. @xref{Query Replace}, for more information on query replace.
-This command works only with the etags backend.
@vindex tags-case-fold-search
@cindex case-sensitivity and tags search
@@ -1976,19 +1968,21 @@ has no special query replace meaning. You can resume
the query
replace subsequently by typing @kbd{M-x tags-loop-continue}; this
command resumes the last tags search or replace command that you did.
For instance, to skip the rest of the current file, you can type
address@hidden> M-x tags-loop-continue}.
address@hidden@kbd{M-> M-x tags-loop-continue}}.
- The commands in this section carry out much broader searches than
-the @code{xref-find-definitions} family. The
+ Note that the commands described above carry out much broader
+searches than the @code{xref-find-definitions} family. The
@code{xref-find-definitions} commands search only for definitions of
identifiers that match your string or regexp. The commands
address@hidden and @code{tags-query-replace} find every occurrence
-of the regexp, as ordinary search commands and replace commands do in
-the current buffer.
address@hidden, @code{tags-search}, and
address@hidden find every occurrence of the identifier or
+regexp, as ordinary search commands and replace commands do in the
+current buffer.
- As an alternative to @code{tags-search}, you can run @command{grep}
-as a subprocess and have Emacs show you the matching lines one by one.
address@hidden Searching}.
+ As an alternative to @code{xref-find-references} and
address@hidden, you can run @command{grep} as a subprocess and
+have Emacs show you the matching lines one by one. @xref{Grep
+Searching}.
@node List Identifiers
@subsubsection Identifier Inquiries
@@ -1996,20 +1990,23 @@ as a subprocess and have Emacs show you the matching
lines one by one.
@table @kbd
@item C-M-i
@itemx address@hidden
-Perform completion on the text around point, using the @code{xref}
-backend if one is available (@code{completion-at-point}).
address@hidden M-x list-tags @key{RET} @var{file} @key{RET}
-Display a list of the tags defined in the program file @var{file}.
+Perform completion on the text around point, using the selected tags
+table if one is loaded (@code{completion-at-point}).
@item M-x xref-find-apropos @key{RET} @var{regexp} @key{RET}
Display a list of all known identifiers matching @var{regexp}.
address@hidden M-x list-tags @key{RET} @var{file} @key{RET}
+Display a list of the identifiers defined in the program file
address@hidden
address@hidden M-x next-file
+Visit files recorded in the selected tags table.
@end table
@cindex completion (symbol names)
In most programming language modes, you can type @kbd{C-M-i} or
@address@hidden (@code{completion-at-point}) to complete the symbol
-at point. If there is an @code{xref} backend available, this command
-can use it to generate completion candidates more intelligently.
address@hidden Completion}.
+at point. If there is a tags table loaded, this command can use it to
+generate completion candidates more intelligently. @xref{Symbol
+Completion}.
@findex list-tags
@kbd{M-x list-tags} reads the name of one of the files covered by
@@ -2044,12 +2041,15 @@ for details.
The first time it is called, it visits the first file covered by the
table. Each subsequent call visits the next covered file, unless a
prefix argument is supplied, in which case it returns to the first
-file. This command works only with the etags backend.
+file. This command requires a tags table to be selected.
@node Tags Tables
@subsection Tags Tables
@cindex tags and tag tables
address@hidden tag
+ A @dfn{tag} is a synonym for identifier reference. @xref{Xref}.
+
A @dfn{tags table} records the tags extracted by scanning the source
code of a certain program or a certain document. Tags extracted from
generated files reference the original files, rather than the
diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index e4bd85c..780e00c 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -1358,7 +1358,7 @@ the @address@hidden key is usually reserved by the window
manager
for switching graphical windows, so you should type @kbd{C-M-i} or
@address@hidden @key{TAB}} instead.
address@hidden xref-based completion
address@hidden tags-based completion
@findex completion-at-point
@cindex Lisp symbol completion
@cindex completion (Lisp symbols)
@@ -1368,7 +1368,7 @@ which generates its completion list in a flexible way.
If Semantic
mode is enabled, it tries to use the Semantic parser data for
completion (@pxref{Semantic}). If Semantic mode is not enabled or
fails at performing completion, it tries to complete using the
-available @code{xref} backend (@pxref{Xref}). If in Emacs Lisp mode, it
+selected tags table (@pxref{Tags Tables}). If in Emacs Lisp mode, it
performs completion using the function, variable, or property names
defined in the current Emacs session.
diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index bef74e3..e854646 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -12,10 +12,10 @@ a string. Emacs also has commands to replace occurrences
of a string
with a different string. There are also commands that do the same
thing, but search for patterns instead of fixed strings.
- You can also search multiple files under the control of an
address@hidden backend (@pxref{Identifier Search}) or through the Dired
address@hidden command (@pxref{Operating on Files}), or ask the @code{grep}
-program to do it (@pxref{Grep Searching}).
+ You can also search multiple files under the control of @code{xref}
+(@pxref{Identifier Search}) or through the Dired @kbd{A} command
+(@pxref{Operating on Files}), or ask the @code{grep} program to do it
+(@pxref{Grep Searching}).
@menu
* Incremental Search:: Search happens as you type the string.
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index dee43ce..9c1df89 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -691,6 +691,14 @@ default is the return value of
@code{this-command-keys-vector}.
@xref{Definition of this-command-keys-vector}.
@end defun
address@hidden funcall-interactively function &rest arguments
+This function works like @code{funcall} (@pxref{Calling Functions}),
+but it makes the call look like an interactive invocation: a call to
address@hidden inside @var{function} will return
address@hidden If @var{function} is not a command, it is called without
+signaling an error.
address@hidden defun
+
@defun command-execute command &optional record-flag keys special
@cindex keyboard macro execution
This function executes @var{command}. The argument @var{command} must
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index 1c6674c..614b7db 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -1188,8 +1188,8 @@ named, this parameter will be @code{nil}.
@cindex window position on display
@cindex frame position
- Position parameters' values are normally measured in pixels, but on
-text terminals they count characters or lines instead.
+ Position parameters' values are measured in pixels. (Note that none
+of these parameters exist on TTY frames.)
@table @code
@vindex left, a frame parameter
@@ -2637,18 +2637,19 @@ defined in the file @file{lisp/term/x-win.el}. Use
@kbd{M-x apropos
@cindex primary selection
@cindex secondary selection
- In the X window system, data can be transferred between different
-applications by means of @dfn{selections}. X defines an arbitrary
-number of @dfn{selection types}, each of which can store its own data;
-however, only three are commonly used: the @dfn{clipboard},
address@hidden selection}, and @dfn{secondary selection}. @xref{Cut and
-Paste,, Cut and Paste, emacs, The GNU Emacs Manual}, for Emacs
-commands that make use of these selections. This section documents
-the low-level functions for reading and setting X selections.
+ In window systems, such as X, data can be transferred between
+different applications by means of @dfn{selections}. X defines an
+arbitrary number of @dfn{selection types}, each of which can store its
+own data; however, only three are commonly used: the @dfn{clipboard},
address@hidden selection}, and @dfn{secondary selection}. Other window
+systems support only the clipboard. @xref{Cut and Paste,, Cut and
+Paste, emacs, The GNU Emacs Manual}, for Emacs commands that make use
+of these selections. This section documents the low-level functions
+for reading and setting window-system selections.
address@hidden Command x-set-selection type data
-This function sets an X selection. It takes two arguments: a
-selection type @var{type}, and the value to assign to it, @var{data}.
address@hidden Command gui-set-selection type data
+This function sets a window-system selection. It takes two arguments:
+a selection type @var{type}, and the value to assign to it, @var{data}.
@var{type} should be a symbol; it is usually one of @code{PRIMARY},
@code{SECONDARY} or @code{CLIPBOARD}. These are symbols with
@@ -2665,14 +2666,14 @@ stands for text in the overlay or between the markers.
The argument
This function returns @var{data}.
@end deffn
address@hidden x-get-selection &optional type data-type
-This function accesses selections set up by Emacs or by other X
-clients. It takes two optional arguments, @var{type} and
address@hidden gui-get-selection &optional type data-type
+This function accesses selections set up by Emacs or by other
+programs. It takes two optional arguments, @var{type} and
@var{data-type}. The default for @var{type}, the selection type, is
@code{PRIMARY}.
The @var{data-type} argument specifies the form of data conversion to
-use, to convert the raw data obtained from another X client into Lisp
+use, to convert the raw data obtained from another program into Lisp
data. Meaningful values include @code{TEXT}, @code{STRING},
@code{UTF8_STRING}, @code{TARGETS}, @code{LENGTH}, @code{DELETE},
@code{FILE_NAME}, @code{CHARACTER_POSITION}, @code{NAME},
@@ -2680,7 +2681,8 @@ data. Meaningful values include @code{TEXT},
@code{STRING},
@code{HOST_NAME}, @code{USER}, @code{CLASS}, @code{ATOM}, and
@code{INTEGER}. (These are symbols with upper-case names in accord
with X conventions.) The default for @var{data-type} is
address@hidden
address@hidden Window systems other than X usually support only a
+small subset of these types, in addition to @code{STRING}.
@end defun
@defopt selection-coding-system
@@ -2692,10 +2694,15 @@ converts to the text representation that X11 normally
uses.
@cindex clipboard support (for MS-Windows)
When Emacs runs on MS-Windows, it does not implement X selections in
-general, but it does support the clipboard. @code{x-get-selection}
-and @code{x-set-selection} on MS-Windows support the text data type
+general, but it does support the clipboard. @code{gui-get-selection}
+and @code{gui-set-selection} on MS-Windows support the text data type
only; if the clipboard holds other types of data, Emacs treats the
-clipboard as empty.
+clipboard as empty. The supported data type is @code{STRING}.
+
+For backward compatibility, there are obsolete aliases
address@hidden and @code{x-set-selection}, which were the
+names of @code{gui-get-selection} and @code{gui-set-selection} before
+Emacs 25.1.
@node Drag and Drop
@section Drag and Drop
diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
index e596bad..1e8e754 100644
--- a/doc/lispref/functions.texi
+++ b/doc/lispref/functions.texi
@@ -623,6 +623,96 @@ definition will have no effect on them.
and tells the Lisp compiler to perform inline expansion on it.
@xref{Inline Functions}.
+ Alternatively, you can define a function by providing the code which
+will inline it as a compiler macro. The following macros make this
+possible.
+
address@hidden FIXME: Can define-inline use the interactive spec?
address@hidden define-inline name args [doc] [declare] address@hidden
+Define a function @var{name} by providing code that does its inlining,
+as a compiler macro. The function will accept the argument list
address@hidden and will have the specified @var{body}.
+
+If present, @var{doc} should be the function's documentation string
+(@pxref{Function Documentation}); @var{declare}, if present, should be
+a @code{declare} form (@pxref{Declare Form}) specifying the function's
+metadata.
address@hidden defmac
+
+Functions defined via @code{define-inline} have several advantages
+with respect to macros defined by @code{defsubst} or @code{defmacro}:
+
address@hidden @minus
address@hidden
+They can be passed to @code{mapcar} (@pxref{Mapping Functions}).
+
address@hidden
+They are more efficient.
+
address@hidden
+They can be used as @dfn{place forms} to store values
+(@pxref{Generalized Variables}).
+
address@hidden
+They behave in a more predictable way than @code{cl-defsubst}
+(@pxref{Argument Lists,,, cl, Common Lisp Extensions for GNU Emacs
+Lisp}).
address@hidden itemize
+
+Like @code{defmacro}, a function inlined with @code{define-inline}
+inherits the scoping rules, either dynamic or lexical, from the call
+site. @xref{Variable Scoping}.
+
+The following macros should be used in the body of a function defined
+by @code{define-inline}.
+
address@hidden inline-quote expression
+Quote @var{expression} for @code{define-inline}. This is similar to
+the backquote (@pxref{Backquote}), but quotes code and accepts only
address@hidden,}, not @code{,@@}.
address@hidden defmac
+
address@hidden inline-letevals (address@hidden) address@hidden
+This is is similar to @code{let} (@pxref{Local Variables}): it sets up
+local variables as specified by @var{bindings}, and then evaluates
address@hidden with those bindings in effect. Each element of
address@hidden should be either a symbol or a list of the form
address@hidden@code{(@var{var} @var{expr})}}; the result is to evaluate
address@hidden and bind @var{var} to the result. The tail of
address@hidden can be either @code{nil} or a symbol which should hold
+a list of arguments, in which case each argument is evaluated, and the
+symbol is bound to the resulting list.
address@hidden defmac
+
address@hidden inline-const-p expression
+Return address@hidden if the value of @var{expression} is already
+known.
address@hidden defmac
+
address@hidden inline-const-val expression
+Return the value of @var{expression}.
address@hidden defmac
+
address@hidden inline-error format &rest args
+Signal an error, formatting @var{args} according to @var{format}.
address@hidden defmac
+
+Here's an example of using @code{define-inline}:
+
address@hidden
+(define-inline myaccessor (obj)
+ (inline-letevals (obj)
+ (inline-quote (if (foo-p ,obj) (aref (cdr ,obj) 3) (aref ,obj 2)))))
address@hidden lisp
+
address@hidden
+This is equivalent to
+
address@hidden
+(defsubst myaccessor (obj)
+ (if (foo-p obj) (aref (cdr obj) 3) (aref obj 2)))
address@hidden lisp
+
@node Calling Functions
@section Calling Functions
@cindex function invocation
@@ -664,6 +754,10 @@ they make sense only when given the unevaluated argument
expressions. @code{funcall} cannot provide these because, as we saw
above, it never knows them in the first place.
+If you need to use @code{funcall} to call a command and make it behave
+as if invoked interactively, use @code{funcall-interactively}
+(@pxref{Interactive Call}).
+
@example
@group
(setq f 'list)
@@ -1706,19 +1800,24 @@ features of Emacs, you should not make a function
inline, even if it's
small, unless its speed is really crucial, and you've timed the code
to verify that using @code{defun} actually has performance problems.
- It's possible to define a macro to expand into the same code that an
-inline function would execute (@pxref{Macros}). But the macro would
-be limited to direct use in expressions---a macro cannot be called
-with @code{apply}, @code{mapcar} and so on. Also, it takes some work
-to convert an ordinary function into a macro. To convert it into an
-inline function is easy; just replace @code{defun} with
address@hidden Since each argument of an inline function is
-evaluated exactly once, you needn't worry about how many times the
-body uses the arguments, as you do for macros.
-
After an inline function is defined, its inline expansion can be
performed later on in the same file, just like macros.
+ It's possible to use @code{defsubst} to define a macro to expand
+into the same code that an inline function would execute
+(@pxref{Macros}). But the macro would be limited to direct use in
+expressions---a macro cannot be called with @code{apply},
address@hidden and so on. Also, it takes some work to convert an
+ordinary function into a macro. To convert it into an inline function
+is easy; just replace @code{defun} with @code{defsubst}. Since each
+argument of an inline function is evaluated exactly once, you needn't
+worry about how many times the body uses the arguments, as you do for
+macros.
+
+ As an alternative to @code{defsubst}, you can use
address@hidden to define functions via their exhaustive compiler
+macro. @xref{Defining Functions, define-inline}.
+
@node Declare Form
@section The @code{declare} Form
@findex declare
diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi
index d961caf..c18c408 100644
--- a/doc/lispref/lists.texi
+++ b/doc/lispref/lists.texi
@@ -1556,6 +1556,14 @@ keys may not be symbols:
@end smallexample
@end defun
address@hidden alist-get key value &optional default
+This function is like @code{assq}, but instead of returning the entire
+association for @var{key}, @code{(@var{key} . @var{value})}, it
+returns just the @var{value}. It returns @var{default} if @var{key}
+is not found in @var{alist}, defaulting to @code{nil} if @var{default}
+is omitted.
address@hidden defun
+
@defun rassq value alist
This function returns the first association with value @var{value} in
@var{alist}. It returns @code{nil} if no association in @var{alist} has
diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi
index 18e67f1..06900a4 100644
--- a/doc/lispref/loading.texi
+++ b/doc/lispref/loading.texi
@@ -73,12 +73,15 @@ To find the file, @code{load} first looks for a file named
@var{filename} with the extension @samp{.elc} appended. If such a
file exists, it is loaded. If there is no file by that name, then
@code{load} looks for a file named @address@hidden If that
-file exists, it is loaded. Finally, if neither of those names is
-found, @code{load} looks for a file named @var{filename} with nothing
-appended, and loads it if it exists. (The @code{load} function is not
-clever about looking at @var{filename}. In the perverse case of a
-file named @file{foo.el.el}, evaluation of @code{(load "foo.el")} will
-indeed find it.)
+file exists, it is loaded. If Emacs was compiled with support for
+dynamic modules (@pxref{Dynamic Modules}), @code{load} next looks for
+a file named @address@hidden@var{ext}}, where @var{ext} is a
+system-dependent file-name extension of shared libraries. Finally, if
+neither of those names is found, @code{load} looks for a file named
address@hidden with nothing appended, and loads it if it exists. (The
address@hidden function is not clever about looking at @var{filename}.
+In the perverse case of a file named @file{foo.el.el}, evaluation of
address@hidden(load "foo.el")} will indeed find it.)
If Auto Compression mode is enabled, as it is by default, then if
@code{load} can not find a file, it searches for a compressed version
@@ -100,7 +103,8 @@ being tried.
If the optional argument @var{must-suffix} is address@hidden, then
@code{load} insists that the file name used must end in either
@samp{.el} or @samp{.elc} (possibly extended with a compression
-suffix), unless it contains an explicit directory name.
+suffix) or the shared-library extension, unless it contains an
+explicit directory name.
If the option @code{load-prefer-newer} is address@hidden, then when
searching suffixes, @code{load} selects whichever version of a file
diff --git a/doc/lispref/macros.texi b/doc/lispref/macros.texi
index 7f3b670..3f9db8c 100644
--- a/doc/lispref/macros.texi
+++ b/doc/lispref/macros.texi
@@ -160,6 +160,12 @@ expand the embedded calls to @code{inc}:
@end defun
address@hidden macroexpand-1 form &optional environment
+This function expands macros like @code{macroexpand}, but it only
+performs one step of the expansion: if the result is another macro
+call, @code{macroexpand-1} will not expand it.
address@hidden defun
+
@node Compiling Macros
@section Macros and Byte Compilation
@cindex byte-compiling macros
diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi
index 95723ca..091db5e 100644
--- a/doc/lispref/strings.texi
+++ b/doc/lispref/strings.texi
@@ -571,13 +571,19 @@ no characters is less than any other string.
@end example
Symbols are also allowed as arguments, in which case their print names
-are used.
+are compared.
@end defun
@defun string-lessp string1 string2
@code{string-lessp} is another name for @code{string<}.
@end defun
address@hidden string-greaterp string1 string2
+This function returns the result of comparing @var{string1} and
address@hidden in the opposite order, i.e., it is equivalent to calling
address@hidden(string-lessp @var{string2} @var{string1})}.
address@hidden defun
+
@cindex locale-dependent string comparison
@defun string-collate-lessp string1 string2 &optional locale ignore-case
This function returns @code{t} if @var{string1} is less than
diff --git a/doc/lispref/symbols.texi b/doc/lispref/symbols.texi
index c99f993..8c1ec3d 100644
--- a/doc/lispref/symbols.texi
+++ b/doc/lispref/symbols.texi
@@ -461,10 +461,23 @@ You could define @code{put} in terms of @code{setplist}
and
@end example
@end defun
address@hidden function-get symbol property
address@hidden function-get symbol property &optional autoload
This function is identical to @code{get}, except that if @var{symbol}
is the name of a function alias, it looks in the property list of the
-symbol naming the actual function. @xref{Defining Functions}.
+symbol naming the actual function. @xref{Defining Functions}. If the
+optional argument @var{autoload} is address@hidden, and @var{symbol}
+is auto-loaded, this function will try to autoload it, since
+autoloading might set @var{property} of @var{symbol}. If
address@hidden is the symbol @code{macro}, only try autoloading if
address@hidden is an auto-loaded macro.
address@hidden defun
+
address@hidden function-put function property value
+This function sets @var{property} of @var{function} to @var{value}.
address@hidden should be a symbol. This function is preferred to
+calling @code{put} for setting properties of a function, because it
+will allow us some day to implement remapping of old properties to new
+ones.
@end defun
@node Standard Properties
diff --git a/etc/NEWS b/etc/NEWS
index 56f0ec3..9fbe695 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -95,6 +95,7 @@ by setting `autoload-timestamps' to nil.
This builds Emacs with Cairo drawing. As a side effect, it provides
support for built-in printing, when Emacs was built with GTK+.
++++
** New configure option --with-modules.
This enables support for loading dynamic modules; see below.
@@ -178,6 +179,7 @@ and can contain escape sequences for command keys, quotes,
and the like.
* Changes in Emacs 25.1
++++
** Emacs can now load shared/dynamic libraries (modules).
A dynamic Emacs module is a shared library that provides additional
functionality for use in Emacs Lisp programs, just like a package
@@ -230,12 +232,6 @@ the `network-security-level' variable.
puny.el library, so that one can visit web sites like
"http://méxico.icom.museum".
-** If Emacs isn't built with TLS support, an external TLS-capable
-program is used instead. This program used to be run in --insecure
-mode by default, but has now changed to be secure instead, and will
-fail if you try to connect to non-verifiable hosts. This is
-controlled by the `tls-program' variable.
-
+++
** C-h l now also lists the commands that were run.
@@ -378,6 +374,17 @@ current package keywords are recognized. Set the new
option
It's meant for use together with `compile':
emacs -batch --eval "(checkdoc-file \"subr.el\")"
+** Desktop
+
+---
+*** The desktop format version has been upgraded from 206 to 208.
+Although Emacs 25.1 can read a version 206 desktop, earlier Emacsen
+cannot read a version 208 desktop. To upgrade your desktop file, you
+must explicitly request the upgrade, by C-u M-x desktop-save. You are
+recommended to do this as soon as you have firmly upgraded to Emacs
+25.1 (or later). Should you ever need to downgrade your desktop file
+to version 206, you can do this with C-u C-u M-x desktop-save.
+
+++
** New function `bookmark-set-no-overwrite' bound to C-x r M.
It raises an error if a bookmark of that name already exists,
@@ -856,6 +863,13 @@ See the doc string of `sh-indent-after-continuation' for
details.
---
*** Fatal TLS errors are now silent by default.
+---
+*** If Emacs isn't built with TLS support, an external TLS-capable
+program is used instead. This program used to be run in --insecure
+mode by default, but has now changed to be secure instead, and will
+fail if you try to connect to non-verifiable hosts. This is
+controlled by the `tls-program' variable.
+
** URL
+++
@@ -1498,11 +1512,14 @@ 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.
++++
** define-inline provides a new way to define inlinable functions.
-** New function `macroexpand-1' to perform a single step of macroexpansion.
++++
+** New function `macroexpand-1' to perform a single step of macro expansion.
-** Some "x-*" were obsoleted:
++++
+** Some "x-*" functions were obsoleted and/or renamed:
*** x-select-text is renamed gui-select-text.
*** x-selection-value is renamed gui-selection-value.
*** x-get-selection is renamed gui-get-selection.
@@ -1510,6 +1527,7 @@ evaluated (and should return a string) when the closure
is built.
*** x-get-selection-value is renamed to gui-get-primary-selection.
*** x-set-selection is renamed to gui-set-selection
++++
** New function `string-greaterp', which return the opposite result of
`string-lessp'.
@@ -1533,12 +1551,15 @@ emulates the behavior of modern Posix platforms when
the locale's
codeset is "UTF-8" (as in "en_US.UTF-8"). This is needed because
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 `funcall-interactively', which works like `funcall'
but makes `called-interactively-p' treat the function as (you guessed it)
called interactively.
++++
** New function `function-put' to use instead of `put' for function properties.
+++
diff --git a/lisp/desktop.el b/lisp/desktop.el
index cb973c4..e795d9c 100644
--- a/lisp/desktop.el
+++ b/lisp/desktop.el
@@ -140,8 +140,15 @@
(defvar desktop-file-version "208"
"Version number of desktop file format.
-Written into the desktop file and used at desktop read to provide
-backward compatibility.")
+Used at desktop read to provide backward compatibility.")
+
+(defconst desktop-native-file-version 208
+ "Format version of the current desktop package, an integer.")
+(defvar desktop-io-file-version nil
+ "The format version of the current desktop file (an integer) or nil.")
+;; Note: Historically, the version number is embedded in the entry for
+;; each buffer. It is highly inadvisable for different buffer entries
+;; to have different format versions.
;; ----------------------------------------------------------------------------
;; USER OPTIONS -- settings you might want to play with.
@@ -693,6 +700,7 @@ deletes all frames except the selected one (and its
minibuffer frame,
if different)."
(interactive)
(desktop-lazy-abort)
+ (setq desktop-io-file-version nil)
(dolist (var desktop-globals-to-clear)
(if (symbolp var)
(eval `(setq-default ,var nil))
@@ -781,44 +789,46 @@ buffer, which is (in order):
local variables;
auxiliary information given by `desktop-var-serdes-funs'."
(set-buffer buffer)
- (list
- ;; base name of the buffer; replaces the buffer name if managed by uniquify
- (and (fboundp 'uniquify-buffer-base-name) (uniquify-buffer-base-name))
- ;; basic information
- (desktop-file-name (buffer-file-name) desktop-dirname)
- (buffer-name)
- major-mode
- ;; minor modes
- (let (ret)
- (dolist (minor-mode (mapcar #'car minor-mode-alist) ret)
- (and (boundp minor-mode)
- (symbol-value minor-mode)
- (let* ((special (assq minor-mode desktop-minor-mode-table))
- (value (cond (special (cadr special))
- ((functionp minor-mode) minor-mode))))
- (when value (cl-pushnew value ret))))))
- ;; point and mark, and read-only status
- (point)
- (list (mark t) mark-active)
- buffer-read-only
- ;; auxiliary information
- (when (functionp desktop-save-buffer)
- (funcall desktop-save-buffer desktop-dirname))
- ;; local variables
- (let ((loclist (buffer-local-variables))
- (ll nil))
- (dolist (local desktop-locals-to-save)
- (let ((here (assq local loclist)))
- (cond (here
- (push here ll))
- ((member local loclist)
- (push local ll)))))
- ll)
- (mapcar (lambda (record)
- (let ((var (car record)))
- (list var
- (funcall (cadr record) (symbol-value var)))))
- desktop-var-serdes-funs)))
+ `(
+ ;; base name of the buffer; replaces the buffer name if managed by uniquify
+ ,(and (fboundp 'uniquify-buffer-base-name) (uniquify-buffer-base-name))
+ ;; basic information
+ ,(desktop-file-name (buffer-file-name) desktop-dirname)
+ ,(buffer-name)
+ ,major-mode
+ ;; minor modes
+ ,(let (ret)
+ (dolist (minor-mode (mapcar #'car minor-mode-alist) ret)
+ (and (boundp minor-mode)
+ (symbol-value minor-mode)
+ (let* ((special (assq minor-mode desktop-minor-mode-table))
+ (value (cond (special (cadr special))
+ ((functionp minor-mode) minor-mode))))
+ (when value (cl-pushnew value ret))))))
+ ;; point and mark, and read-only status
+ ,(point)
+ ,(list (mark t) mark-active)
+ ,buffer-read-only
+ ;; auxiliary information
+ ,(when (functionp desktop-save-buffer)
+ (funcall desktop-save-buffer desktop-dirname))
+ ;; local variables
+ ,(let ((loclist (buffer-local-variables))
+ (ll nil))
+ (dolist (local desktop-locals-to-save)
+ (let ((here (assq local loclist)))
+ (cond (here
+ (push here ll))
+ ((member local loclist)
+ (push local ll)))))
+ ll)
+ ,@(when (>= desktop-io-file-version 208)
+ (list
+ (mapcar (lambda (record)
+ (let ((var (car record)))
+ (list var
+ (funcall (cadr record) (symbol-value var)))))
+ desktop-var-serdes-funs)))))
;; ----------------------------------------------------------------------------
(defun desktop--v2s (value)
@@ -983,20 +993,41 @@ Frames with a non-nil `desktop-dont-save' parameter are
not saved."
:predicate #'desktop--check-dont-save))))
;;;###autoload
-(defun desktop-save (dirname &optional release only-if-changed)
+(defun desktop-save (dirname &optional release only-if-changed version)
"Save the desktop in a desktop file.
Parameter DIRNAME specifies where to save the desktop file.
-Optional parameter RELEASE says whether we're done with this desktop.
-If ONLY-IF-CHANGED is non-nil, compare the current desktop information
-to that in the desktop file, and if the desktop information has not
-changed since it was last saved then do not rewrite the file."
+Optional parameter RELEASE says whether we're done with this
+desktop. If ONLY-IF-CHANGED is non-nil, compare the current
+desktop information to that in the desktop file, and if the
+desktop information has not changed since it was last saved then
+do not rewrite the file.
+
+This function can save the desktop in either format version
+208 (which only Emacs 25.1 and later can read) or version
+206 (which is readable by any Emacs from version 22.1 onwards).
+By default, it will use the same format the desktop file had when
+it was last saved, or version 208 when writing a fresh desktop
+file.
+
+To upgrade a version 206 file to version 208, call this command
+explicitly with a bare prefix argument: C-u M-x desktop-save.
+You are recommended to do this once you have firmly upgraded to
+Emacs 25.1 (or later). To downgrade a version 208 file to version
+206, use a double command prefix: C-u C-u M-x desktop-save.
+Confirmation will be requested in either case. In a non-interactive
+call, VERSION can be given as an integer, either 206 or 208, which
+will be accepted as the format version in which to save the file
+without further confirmation."
(interactive (list
;; Or should we just use (car desktop-path)?
(let ((default (if (member "." desktop-path)
default-directory
user-emacs-directory)))
(read-directory-name "Directory to save desktop file in: "
- default default t))))
+ default default t))
+ nil
+ nil
+ current-prefix-arg))
(setq desktop-dirname (file-name-as-directory (expand-file-name dirname)))
(save-excursion
(let ((eager desktop-restore-eager)
@@ -1017,12 +1048,34 @@ changed since it was last saved then do not rewrite the
file."
(desktop-release-lock)
(unless (and new-modtime (desktop-owner)) (desktop-claim-lock)))
+ ;; What format are we going to write the file in?
+ (setq desktop-io-file-version
+ (cond
+ ((equal version '(4))
+ (if (or (eq desktop-io-file-version 208)
+ (yes-or-no-p "Save desktop file in format 208 \
+\(Readable by Emacs 25.1 and later only)? "))
+ 208
+ (or desktop-io-file-version desktop-native-file-version)))
+ ((equal version '(16))
+ (if (or (eq desktop-io-file-version 206)
+ (yes-or-no-p "Save desktop file in format 206 \
+\(Readable by all Emacs versions since 22.1)? "))
+ 206
+ (or desktop-io-file-version desktop-native-file-version)))
+ ((memq version '(206 208))
+ version)
+ ((null desktop-io-file-version) ; As yet, no desktop file
exists.
+ desktop-native-file-version)
+ (t
+ desktop-io-file-version)))
+
(with-temp-buffer
(insert
";; -*- mode: emacs-lisp; coding: emacs-mule; -*-\n"
desktop-header
";; Created " (current-time-string) "\n"
- ";; Desktop file format version " desktop-file-version "\n"
+ ";; Desktop file format version " (format "%d"
desktop-io-file-version) "\n"
";; Emacs version " emacs-version "\n")
(save-excursion (run-hooks 'desktop-save-hook))
(goto-char (point-max))
@@ -1052,7 +1105,7 @@ changed since it was last saved then do not rewrite the
file."
"desktop-create-buffer"
"desktop-append-buffer-args")
" "
- desktop-file-version)
+ (format "%d" desktop-io-file-version))
;; If there's a non-empty base name, we save it instead of the
buffer name
(when (and base (not (string= base "")))
(setcar (nthcdr 1 l) base))
@@ -1390,6 +1443,8 @@ and try to load that."
compacted-vars
&rest _unsupported)
+ (setq desktop-io-file-version file-version)
+
(let ((desktop-file-version file-version)
(desktop-buffer-file-name buffer-filename)
(desktop-buffer-name buffer-name)
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index a678fca..ab10ede 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -2713,6 +2713,41 @@ with the command \\[tags-loop-continue]."
(tags-query-replace from to delimited
'(dired-get-marked-files nil nil 'dired-nondirectory-p)))
+(declare-function xref--show-xrefs "xref")
+(declare-function xref-query-replace "xref")
+
+;;;###autoload
+(defun dired-do-find-regexp (regexp)
+ "Find all matches for REGEXP in all marked files, recursively."
+ (interactive "sSearch marked files (regexp): ")
+ (require 'grep)
+ (defvar grep-find-ignored-files)
+ (let* ((files (dired-get-marked-files))
+ (ignores (nconc (mapcar
+ (lambda (s) (concat s "/"))
+ vc-directory-exclusion-list)
+ grep-find-ignored-files))
+ (xrefs (cl-mapcan
+ (lambda (file)
+ (xref-collect-matches regexp "*" file
+ (and (file-directory-p file)
+ ignores)))
+ files)))
+ (unless xrefs
+ (user-error "No matches for: %s" regexp))
+ (xref--show-xrefs xrefs nil t)))
+
+;;;###autoload
+(defun dired-do-find-regexp-and-replace (from to)
+ "Replace matches of FROM with TO, in all marked files, recursively."
+ (interactive
+ (let ((common
+ (query-replace-read-args
+ "Query replace regexp in marked files" t t)))
+ (list (nth 0 common) (nth 1 common))))
+ (with-current-buffer (dired-do-find-regexp from)
+ (xref-query-replace from to)))
+
(defun dired-nondirectory-p (file)
(not (file-directory-p file)))
diff --git a/lisp/dired.el b/lisp/dired.el
index 63124fc..6c7445c 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -1453,7 +1453,7 @@ Do so according to the former subdir alist
OLD-SUBDIR-ALIST."
(define-key map "." 'dired-clean-directory)
(define-key map "~" 'dired-flag-backup-files)
;; Upper case keys (except !) for operating on the marked files
- (define-key map "A" 'dired-do-search)
+ (define-key map "A" 'dired-do-find-regexp)
(define-key map "C" 'dired-do-copy)
(define-key map "B" 'dired-do-byte-compile)
(define-key map "D" 'dired-do-delete)
@@ -1463,7 +1463,7 @@ Do so according to the former subdir alist
OLD-SUBDIR-ALIST."
(define-key map "M" 'dired-do-chmod)
(define-key map "O" 'dired-do-chown)
(define-key map "P" 'dired-do-print)
- (define-key map "Q" 'dired-do-query-replace-regexp)
+ (define-key map "Q" 'dired-do-find-regexp-and-replace)
(define-key map "R" 'dired-do-rename)
(define-key map "S" 'dired-do-symlink)
(define-key map "T" 'dired-do-touch)
diff --git a/lisp/emacs-lisp/inline.el b/lisp/emacs-lisp/inline.el
index 56780fb..058c56c 100644
--- a/lisp/emacs-lisp/inline.el
+++ b/lisp/emacs-lisp/inline.el
@@ -102,7 +102,7 @@ VARS should be a list of elements of the form (VAR EXP) or
just VAR, in case
EXP is equal to VAR. The result is to evaluate EXP and bind the result to VAR.
The tail of VARS can be either nil or a symbol VAR which should hold a list
-of arguments,in which case each argument is evaluated and the resulting
+of arguments, in which case each argument is evaluated and the resulting
new list is re-bound to VAR.
After VARS is handled, BODY is evaluated in the new environment."
diff --git a/lisp/net/shr.el b/lisp/net/shr.el
index 2511d67..290a642 100644
--- a/lisp/net/shr.el
+++ b/lisp/net/shr.el
@@ -1617,7 +1617,9 @@ The preference is a float determined from
`shr-prefer-media-type'."
(shr-insert-table (shr-make-table dom sketch-widths t) sketch-widths)))
(defun shr-table-body (dom)
- (let ((tbodies (dom-by-tag dom 'tbody)))
+ (let ((tbodies (seq-filter (lambda (child)
+ (eq (dom-tag child) 'tbody))
+ (dom-children dom))))
(cond
((null tbodies)
dom)
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index a972def..85f3907 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -264,7 +264,6 @@ DIRS must contain directory names."
(symbol-value var)))
(declare-function grep-read-files "grep")
-(declare-function xref-collect-matches "xref")
(declare-function xref--show-xrefs "xref")
(declare-function xref-backend-identifier-at-point "xref")
(declare-function xref--find-ignores-arguments "xref")
@@ -295,8 +294,8 @@ pattern to search for."
(project--find-regexp-in dirs regexp pr)))
(defun project--read-regexp ()
- (read-regexp "Find regexp"
- (xref-backend-identifier-at-point (xref-find-backend))))
+ (let ((id (xref-backend-identifier-at-point (xref-find-backend))))
+ (read-regexp "Find regexp" (and id (regexp-quote id)))))
(defun project--find-regexp-in (dirs regexp project)
(require 'grep)
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 8f08b7c..53f8a6b 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -1830,7 +1830,7 @@ It will be properly highlighted even when the call omits
parens.")
"\\)\\s *")
"Regexp to match text that can be followed by a regular expression."))
-(defun ruby-syntax-propertize-function (start end)
+(defun ruby-syntax-propertize (start end)
"Syntactic keywords for Ruby mode. See `syntax-propertize-function'."
(let (case-fold-search)
(goto-char start)
@@ -1856,6 +1856,8 @@ It will be properly highlighted even when the call omits
parens.")
(zerop (skip-syntax-backward "w_")))
(memq (preceding-char) '(?@ ?$))))
(string-to-syntax "_"))))
+ ;; Backtick method redefinition.
+ ("^[ \t]*def +\\(`\\)" (1 "_"))
;; Regular expressions. Start with matching unescaped slash.
("\\(?:\\=\\|[^\\]\\)\\(?:\\\\\\\\\\)*\\(/\\)"
(1 (let ((state (save-excursion (syntax-ppss (match-beginning 1)))))
@@ -1891,6 +1893,9 @@ It will be properly highlighted even when the call omits
parens.")
(1 (prog1 "|" (ruby-syntax-propertize-percent-literal end)))))
(point) end)))
+(define-obsolete-function-alias
+ 'ruby-syntax-propertize-function 'ruby-syntax-propertize "25.1")
+
(defun ruby-syntax-propertize-heredoc (limit)
(let ((ppss (syntax-ppss))
(res '()))
@@ -2252,7 +2257,7 @@ See `font-lock-syntax-table'.")
(setq-local font-lock-keywords ruby-font-lock-keywords)
(setq-local font-lock-syntax-table ruby-font-lock-syntax-table)
- (setq-local syntax-propertize-function #'ruby-syntax-propertize-function))
+ (setq-local syntax-propertize-function #'ruby-syntax-propertize))
;;; Invoke ruby-mode when appropriate
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 6220b4c..2bccd85 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -511,11 +511,18 @@ references displayed in the current *xref* buffer."
(let ((fr (read-regexp "Xref query-replace (regexp)" ".*")))
(list fr
(read-regexp (format "Xref query-replace (regexp) %s with: " fr)))))
- (let (pairs item)
+ (let ((reporter (make-progress-reporter (format "Saving search results...")
+ 0 (line-number-at-pos (point-max))))
+ (counter 0)
+ pairs item)
(unwind-protect
(progn
(save-excursion
(goto-char (point-min))
+ ;; TODO: This list should be computed on-demand instead.
+ ;; As long as the UI just iterates through matches one by
+ ;; one, there's no need to compute them all in advance.
+ ;; Then we can throw away the reporter.
(while (setq item (xref--search-property 'xref-item))
(when (xref-match-length item)
(save-excursion
@@ -535,9 +542,11 @@ references displayed in the current *xref* buffer."
(line-end-position))
(xref-item-summary item))
(user-error "Search results out of date"))
+ (progress-reporter-update reporter (cl-incf counter))
(push (cons beg end) pairs)))))
(setq pairs (nreverse pairs)))
(unless pairs (user-error "No suitable matches here"))
+ (progress-reporter-done reporter)
(xref--query-replace-1 from to pairs))
(dolist (pair pairs)
(move-marker (car pair) nil)
@@ -713,9 +722,9 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
(defvar xref--read-pattern-history nil)
-(defun xref--show-xrefs (xrefs window)
+(defun xref--show-xrefs (xrefs window &optional always-show-list)
(cond
- ((not (cdr xrefs))
+ ((and (not (cdr xrefs)) (not always-show-list))
(xref-push-marker-stack)
(xref--pop-to-location (car xrefs) window))
(t
@@ -866,11 +875,12 @@ tools are used, and when."
(mapc #'kill-buffer
(cl-set-difference (buffer-list) orig-buffers)))))
+;;;###autoload
(defun xref-collect-matches (regexp files dir ignores)
"Collect matches for REGEXP inside FILES in DIR.
FILES is a string with glob patterns separated by spaces.
IGNORES is a list of glob patterns."
- (cl-assert (directory-name-p dir))
+ ;; DIR can also be a regular file for now; let's not advertise that.
(require 'semantic/fw)
(grep-compute-defaults)
(defvar grep-find-template)
@@ -885,6 +895,8 @@ IGNORES is a list of glob patterns."
(orig-buffers (buffer-list))
(buf (get-buffer-create " *xref-grep*"))
(grep-re (caar grep-regexp-alist))
+ (counter 0)
+ reporter
hits)
(with-current-buffer buf
(erase-buffer)
@@ -894,9 +906,17 @@ IGNORES is a list of glob patterns."
(push (cons (string-to-number (match-string 2))
(match-string 1))
hits)))
+ (setq reporter (make-progress-reporter
+ (format "Collecting search results...")
+ 0 (length hits)))
(unwind-protect
- (cl-mapcan (lambda (hit) (xref--collect-matches hit regexp))
+ (cl-mapcan (lambda (hit)
+ (prog1
+ (progress-reporter-update reporter counter)
+ (cl-incf counter))
+ (xref--collect-matches hit regexp))
(nreverse hits))
+ (progress-reporter-done reporter)
;; TODO: Same as above.
(mapc #'kill-buffer
(cl-set-difference (buffer-list) orig-buffers)))))
@@ -922,23 +942,24 @@ IGNORES is a list of glob patterns."
(defun xref--find-ignores-arguments (ignores dir)
;; `shell-quote-argument' quotes the tilde as well.
(cl-assert (not (string-match-p "\\`~" dir)))
- (concat
- (shell-quote-argument "(")
- " -path "
- (mapconcat
- (lambda (ignore)
- (when (string-match-p "/\\'" ignore)
- (setq ignore (concat ignore "*")))
- (if (string-match "\\`\\./" ignore)
- (setq ignore (replace-match dir t t ignore))
- (unless (string-prefix-p "*" ignore)
- (setq ignore (concat "*/" ignore))))
- (shell-quote-argument ignore))
- ignores
- " -o -path ")
- " "
- (shell-quote-argument ")")
- " -prune -o "))
+ (when ignores
+ (concat
+ (shell-quote-argument "(")
+ " -path "
+ (mapconcat
+ (lambda (ignore)
+ (when (string-match-p "/\\'" ignore)
+ (setq ignore (concat ignore "*")))
+ (if (string-match "\\`\\./" ignore)
+ (setq ignore (replace-match dir t t ignore))
+ (unless (string-prefix-p "*" ignore)
+ (setq ignore (concat "*/" ignore))))
+ (shell-quote-argument ignore))
+ ignores
+ " -o -path ")
+ " "
+ (shell-quote-argument ")")
+ " -prune -o ")))
(defun xref--regexp-to-extended (str)
(replace-regexp-in-string
diff --git a/m4/ax_gcc_var_attribute.m4 b/m4/ax_gcc_var_attribute.m4
deleted file mode 100644
index d12fce8..0000000
--- a/m4/ax_gcc_var_attribute.m4
+++ /dev/null
@@ -1,141 +0,0 @@
-# ===========================================================================
-# http://www.gnu.org/software/autoconf-archive/ax_gcc_var_attribute.html
-# ===========================================================================
-#
-# SYNOPSIS
-#
-# AX_GCC_VAR_ATTRIBUTE(ATTRIBUTE)
-#
-# DESCRIPTION
-#
-# This macro checks if the compiler supports one of GCC's variable
-# attributes; many other compilers also provide variable attributes with
-# the same syntax. Compiler warnings are used to detect supported
-# attributes as unsupported ones are ignored by default so quieting
-# warnings when using this macro will yield false positives.
-#
-# The ATTRIBUTE parameter holds the name of the attribute to be checked.
-#
-# If ATTRIBUTE is supported define HAVE_VAR_ATTRIBUTE_<ATTRIBUTE>.
-#
-# The macro caches its result in the ax_cv_have_var_attribute_<attribute>
-# variable.
-#
-# The macro currently supports the following variable attributes:
-#
-# aligned
-# cleanup
-# common
-# nocommon
-# deprecated
-# mode
-# packed
-# tls_model
-# unused
-# used
-# vector_size
-# weak
-# dllimport
-# dllexport
-# init_priority
-#
-# Unsupported variable attributes will be tested against a global integer
-# variable and without any arguments given to the attribute itself; the
-# result of this check might be wrong or meaningless so use with care.
-#
-# LICENSE
-#
-# Copyright (c) 2013 Gabriele Svelto <address@hidden>
-#
-# Copying and distribution of this file, with or without modification, are
-# permitted in any medium without royalty provided the copyright notice
-# and this notice are preserved. This file is offered as-is, without any
-# warranty.
-
-#serial 3
-
-AC_DEFUN([AX_GCC_VAR_ATTRIBUTE], [
- AS_VAR_PUSHDEF([ac_var], [ax_cv_have_var_attribute_$1])
-
- AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [
- AC_LINK_IFELSE([AC_LANG_PROGRAM([
- m4_case([$1],
- [aligned], [
- int foo __attribute__(($1(32)));
- ],
- [cleanup], [
- int bar(int *t) { return *t; };
- ],
- [common], [
- int foo __attribute__(($1));
- ],
- [nocommon], [
- int foo __attribute__(($1));
- ],
- [deprecated], [
- int foo __attribute__(($1)) = 0;
- ],
- [mode], [
- long foo __attribute__(($1(word)));
- ],
- [packed], [
- struct bar {
- int baz __attribute__(($1));
- };
- ],
- [tls_model], [
- __thread int bar1 __attribute__(($1("global-dynamic")));
- __thread int bar2 __attribute__(($1("local-dynamic")));
- __thread int bar3 __attribute__(($1("initial-exec")));
- __thread int bar4 __attribute__(($1("local-exec")));
- ],
- [unused], [
- int foo __attribute__(($1));
- ],
- [used], [
- int foo __attribute__(($1));
- ],
- [vector_size], [
- int foo __attribute__(($1(16)));
- ],
- [weak], [
- int foo __attribute__(($1));
- ],
- [dllimport], [
- int foo __attribute__(($1));
- ],
- [dllexport], [
- int foo __attribute__(($1));
- ],
- [init_priority], [
- struct bar { bar() {} ~bar() {} };
- bar b __attribute__(($1(65535/2)));
- ],
- [
- m4_warn([syntax], [Unsupported attribute $1, the test may
fail])
- int foo __attribute__(($1));
- ]
- )], [
- m4_case([$1],
- [cleanup], [
- int foo __attribute__(($1(bar))) = 0;
- foo = foo + 1;
- ],
- []
- )])
- ],
- dnl GCC doesn't exit with an error if an unknown attribute is
- dnl provided but only outputs a warning, so accept the attribute
- dnl only if no warning were issued.
- [AS_IF([test -s conftest.err],
- [AS_VAR_SET([ac_var], [no])],
- [AS_VAR_SET([ac_var], [yes])])],
- [AS_VAR_SET([ac_var], [no])])
- ])
-
- AS_IF([test yes = AS_VAR_GET([ac_var])],
- [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_VAR_ATTRIBUTE_$1), 1,
- [Define to 1 if the system has the `$1' variable attribute])], [])
-
- AS_VAR_POPDEF([ac_var])
-])
diff --git a/src/conf_post.h b/src/conf_post.h
index 98ff12e..5c332a0 100644
--- a/src/conf_post.h
+++ b/src/conf_post.h
@@ -51,10 +51,21 @@ typedef bool bool_bf;
#endif
#endif
-/* When not using Clang, assume its attributes and features are absent. */
+/* Simulate __has_attribute on compilers that lack it. It is used only
+ on arguments like alloc_size that are handled in this simulation. */
#ifndef __has_attribute
-# define __has_attribute(a) false
-#endif
+# define __has_attribute(a) __has_attribute_##a
+# define __has_attribute_alloc_size (4 < __GNUC__ + (3 <= __GNUC_MINOR__))
+# define __has_attribute_cleanup (3 < __GNUC__ + (4 <= __GNUC_MINOR__))
+# define __has_attribute_externally_visible \
+ (4 < __GNUC__ + (1 <= __GNUC_MINOR__))
+# define __has_attribute_no_address_safety_analysis false
+# define __has_attribute_no_sanitize_address \
+ (4 < __GNUC__ + (8 <= __GNUC_MINOR__))
+#endif
+
+/* Simulate __has_feature on compilers that lack it. It is used only
+ to define ADDRESS_SANITIZER below. */
#ifndef __has_feature
# define __has_feature(a) false
#endif
@@ -222,9 +233,7 @@ extern int emacs_setenv_TZ (char const *);
#define NO_INLINE
#endif
-#if (__clang__ \
- ? __has_attribute (externally_visible) \
- : (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)))
+#if __has_attribute (externally_visible)
#define EXTERNALLY_VISIBLE __attribute__((externally_visible))
#else
#define EXTERNALLY_VISIBLE
@@ -253,9 +262,7 @@ extern int emacs_setenv_TZ (char const *);
# define ATTRIBUTE_MALLOC
#endif
-#if (__clang__ \
- ? __has_attribute (alloc_size) \
- : 4 < __GNUC__ + (3 <= __GNUC_MINOR__))
+#if __has_attribute (alloc_size)
# define ATTRIBUTE_ALLOC_SIZE(args) __attribute__ ((__alloc_size__ args))
#else
# define ATTRIBUTE_ALLOC_SIZE(args)
@@ -278,8 +285,7 @@ extern int emacs_setenv_TZ (char const *);
/* Attribute of functions whose code should not have addresses
sanitized. */
-#if (__has_attribute (no_sanitize_address) \
- || 4 < __GNUC__ + (8 <= __GNUC_MINOR__))
+#if __has_attribute (no_sanitize_address)
# define ATTRIBUTE_NO_SANITIZE_ADDRESS \
__attribute__ ((no_sanitize_address)) ADDRESS_SANITIZER_WORKAROUND
#elif __has_attribute (no_address_safety_analysis)
diff --git a/src/emacs-module.c b/src/emacs-module.c
index b5e044e..79a077b 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -35,8 +35,7 @@ along with GNU Emacs. If not, see
<http://www.gnu.org/licenses/>. */
/* Feature tests. */
-/* True if __attribute__ ((cleanup (...))) works, false otherwise. */
-#ifdef HAVE_VAR_ATTRIBUTE_CLEANUP
+#if __has_attribute (cleanup)
enum { module_has_cleanup = true };
#else
enum { module_has_cleanup = false };
diff --git a/src/fns.c b/src/fns.c
index 977229b..86ad333 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -50,7 +50,8 @@ All integers representable in Lisp, i.e. between
`most-negative-fixnum'
and `most-positive-fixnum', inclusive, are equally likely.
With positive integer LIMIT, return random number in interval [0,LIMIT).
-With argument t, set the random number seed from the current time and pid.
+With argument t, set the random number seed from the system's entropy
+pool if available, otherwise from less-random volatile data such as the time.
With a string argument, set the seed based on the string's contents.
Other values of LIMIT are ignored.
diff --git a/src/gnutls.c b/src/gnutls.c
index a1d058f..01a5983 100644
--- a/src/gnutls.c
+++ b/src/gnutls.c
@@ -1112,15 +1112,17 @@ The return value is a property list with top-level keys
:warnings and
/* Initialize global GnuTLS state to defaults.
Call `gnutls-global-deinit' when GnuTLS usage is no longer needed.
Return zero on success. */
-static Lisp_Object
+Lisp_Object
emacs_gnutls_global_init (void)
{
int ret = GNUTLS_E_SUCCESS;
if (!gnutls_global_initialized)
- ret = gnutls_global_init ();
-
- gnutls_global_initialized = 1;
+ {
+ ret = gnutls_global_init ();
+ if (ret == GNUTLS_E_SUCCESS)
+ gnutls_global_initialized = 1;
+ }
return gnutls_make_error (ret);
}
diff --git a/src/gnutls.h b/src/gnutls.h
index c4fe738..8e879c1 100644
--- a/src/gnutls.h
+++ b/src/gnutls.h
@@ -83,6 +83,7 @@ extern ptrdiff_t emacs_gnutls_record_check_pending
(gnutls_session_t state);
extern void emacs_gnutls_transport_set_errno (gnutls_session_t state, int err);
#endif
extern Lisp_Object emacs_gnutls_deinit (Lisp_Object);
+extern Lisp_Object emacs_gnutls_global_init (void);
#endif
diff --git a/src/sysdep.c b/src/sysdep.c
index e73acec..a86b536 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -99,6 +99,14 @@ along with GNU Emacs. If not, see
<http://www.gnu.org/licenses/>. */
#include "process.h"
#include "cm.h"
+#include "gnutls.h"
+#if 0x020c00 <= GNUTLS_VERSION_NUMBER && !defined WINDOWSNT
+# include <gnutls/crypto.h>
+#else
+# define emacs_gnutls_global_init() Qnil
+# define gnutls_rnd(level, data, len) (-1)
+#endif
+
#ifdef WINDOWSNT
#include <direct.h>
/* In process.h which conflicts with the local copy. */
@@ -2071,36 +2079,56 @@ init_signals (bool dumping)
# endif /* !HAVE_RANDOM */
#endif /* !RAND_BITS */
+#ifdef HAVE_RANDOM
+typedef unsigned int random_seed;
+static void set_random_seed (random_seed arg) { srandom (arg); }
+#elif defined HAVE_LRAND48
+/* Although srand48 uses a long seed, this is unsigned long to avoid
+ undefined behavior on signed integer overflow in init_random. */
+typedef unsigned long int random_seed;
+static void set_random_seed (random_seed arg) { srand48 (arg); }
+#else
+typedef unsigned int random_seed;
+static void set_random_seed (random_seed arg) { srand (arg); }
+#endif
+
void
seed_random (void *seed, ptrdiff_t seed_size)
{
-#if defined HAVE_RANDOM || ! defined HAVE_LRAND48
- unsigned int arg = 0;
-#else
- long int arg = 0;
-#endif
+ random_seed arg = 0;
unsigned char *argp = (unsigned char *) &arg;
unsigned char *seedp = seed;
- ptrdiff_t i;
- for (i = 0; i < seed_size; i++)
+ for (ptrdiff_t i = 0; i < seed_size; i++)
argp[i % sizeof arg] ^= seedp[i];
-#ifdef HAVE_RANDOM
- srandom (arg);
-#else
-# ifdef HAVE_LRAND48
- srand48 (arg);
-# else
- srand (arg);
-# endif
-#endif
+ set_random_seed (arg);
}
void
init_random (void)
{
- struct timespec t = current_timespec ();
- uintmax_t v = getpid () ^ t.tv_sec ^ t.tv_nsec;
- seed_random (&v, sizeof v);
+ random_seed v;
+ if (! (EQ (emacs_gnutls_global_init (), Qt)
+ && gnutls_rnd (GNUTLS_RND_NONCE, &v, sizeof v) == 0))
+ {
+ bool success = false;
+#ifndef WINDOWSNT
+ int fd = emacs_open ("/dev/urandom", O_RDONLY | O_BINARY, 0);
+ if (0 <= fd)
+ {
+ success = emacs_read (fd, &v, sizeof v) == sizeof v;
+ emacs_close (fd);
+ }
+#else
+ success = w32_init_random (&v, sizeof v) == 0;
+#endif
+ if (! success)
+ {
+ /* Fall back to current time value + PID. */
+ struct timespec t = current_timespec ();
+ v = getpid () ^ t.tv_sec ^ t.tv_nsec;
+ }
+ }
+ set_random_seed (v);
}
/*
diff --git a/src/window.c b/src/window.c
index bb414e7..4aeb8b3 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4979,27 +4979,34 @@ window_scroll_pixel_based (Lisp_Object window, int n,
bool whole, bool noerror)
if (n > 0)
{
+ int last_y = it.last_visible_y - this_scroll_margin - 1;
+
/* We moved the window start towards ZV, so PT may be now
in the scroll margin at the top. */
move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
- if (IT_CHARPOS (it) == PT && it.current_y >= this_scroll_margin
+ if (IT_CHARPOS (it) == PT
+ && it.current_y >= this_scroll_margin
+ && it.current_y <= last_y - WINDOW_HEADER_LINE_HEIGHT (w)
&& (NILP (Vscroll_preserve_screen_position)
|| EQ (Vscroll_preserve_screen_position, Qt)))
/* We found PT at a legitimate height. Leave it alone. */
;
- else if (window_scroll_pixel_based_preserve_y >= 0)
- {
- /* If we have a header line, take account of it.
- This is necessary because we set it.current_y to 0, above. */
- move_it_to (&it, -1,
- window_scroll_pixel_based_preserve_x,
- (window_scroll_pixel_based_preserve_y
- - WINDOW_WANTS_HEADER_LINE_P (w)),
- -1, MOVE_TO_Y | MOVE_TO_X);
- SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
- }
else
{
+ if (window_scroll_pixel_based_preserve_y >= 0)
+ {
+ /* Don't enter the scroll margin at the end of the window. */
+ int goal_y = min (last_y, window_scroll_pixel_based_preserve_y);
+
+ /* If we have a header line, take account of it. This
+ is necessary because we set it.current_y to 0, above. */
+ move_it_to (&it, -1,
+ window_scroll_pixel_based_preserve_x,
+ goal_y - WINDOW_HEADER_LINE_HEIGHT (w),
+ -1, MOVE_TO_Y | MOVE_TO_X);
+ }
+
+ /* Get out of the scroll margin at the top of the window. */
while (it.current_y < this_scroll_margin)
{
int prev = it.current_y;
@@ -5023,7 +5030,7 @@ window_scroll_pixel_based (Lisp_Object window, int n,
bool whole, bool noerror)
/* We moved the window start towards BEGV, so PT may be now
in the scroll margin at the bottom. */
move_it_to (&it, PT, -1,
- (it.last_visible_y - CURRENT_HEADER_LINE_HEIGHT (w)
+ (it.last_visible_y - WINDOW_HEADER_LINE_HEIGHT (w)
- this_scroll_margin - 1),
-1,
MOVE_TO_POS | MOVE_TO_Y);
@@ -5074,14 +5081,20 @@ window_scroll_pixel_based (Lisp_Object window, int n,
bool whole, bool noerror)
;
else if (window_scroll_pixel_based_preserve_y >= 0)
{
+ int goal_y = min (it.last_visible_y - this_scroll_margin - 1,
+ window_scroll_pixel_based_preserve_y);
+
+ /* Don't let the preserved screen Y coordinate put us inside
+ any of the two margins. */
+ if (goal_y < this_scroll_margin)
+ goal_y = this_scroll_margin;
SET_TEXT_POS_FROM_MARKER (start, w->start);
start_display (&it, w, start);
/* It would be wrong to subtract CURRENT_HEADER_LINE_HEIGHT
here because we called start_display again and did not
alter it.current_y this time. */
move_it_to (&it, -1, window_scroll_pixel_based_preserve_x,
- window_scroll_pixel_based_preserve_y, -1,
- MOVE_TO_Y | MOVE_TO_X);
+ goal_y, -1, MOVE_TO_Y | MOVE_TO_X);
SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
}
else
@@ -5197,6 +5210,7 @@ window_scroll_line_based (Lisp_Object window, int n, bool
whole, bool noerror)
w->force_start = true;
if (!NILP (Vscroll_preserve_screen_position)
+ && this_scroll_margin == 0
&& (whole || !EQ (Vscroll_preserve_screen_position, Qt)))
{
SET_PT_BOTH (pos, pos_byte);
@@ -5222,8 +5236,16 @@ window_scroll_line_based (Lisp_Object window, int n,
bool whole, bool noerror)
marker_byte_position (opoint_marker));
else if (!NILP (Vscroll_preserve_screen_position))
{
+ int nlines = window_scroll_preserve_vpos;
+
SET_PT_BOTH (pos, pos_byte);
- Fvertical_motion (original_pos, window, Qnil);
+ if (window_scroll_preserve_vpos < this_scroll_margin)
+ nlines = this_scroll_margin;
+ else if (window_scroll_preserve_vpos
+ >= w->total_lines - this_scroll_margin)
+ nlines = w->total_lines - this_scroll_margin - 1;
+ Fvertical_motion (Fcons (make_number
(window_scroll_preserve_hpos),
+ make_number (nlines)), window, Qnil);
}
else
SET_PT (top_margin);
@@ -5249,8 +5271,16 @@ window_scroll_line_based (Lisp_Object window, int n,
bool whole, bool noerror)
{
if (!NILP (Vscroll_preserve_screen_position))
{
+ int nlines = window_scroll_preserve_vpos;
+
SET_PT_BOTH (pos, pos_byte);
- Fvertical_motion (original_pos, window, Qnil);
+ if (window_scroll_preserve_vpos < this_scroll_margin)
+ nlines = this_scroll_margin;
+ else if (window_scroll_preserve_vpos
+ >= ht - this_scroll_margin)
+ nlines = ht - this_scroll_margin - 1;
+ Fvertical_motion (Fcons (make_number
(window_scroll_preserve_hpos),
+ make_number (nlines)), window, Qnil);
}
else
Fvertical_motion (make_number (-1), window, Qnil);
diff --git a/test/manual/etags/CTAGS.good b/test/manual/etags/CTAGS.good
index 245f670..86b019a 100644
--- a/test/manual/etags/CTAGS.good
+++ b/test/manual/etags/CTAGS.good
@@ -438,7 +438,7 @@ Cjava_entries c-src/etags.c /^Cjava_entries (FILE
*inf)$/
Cjava_help c-src/etags.c 551
Cjava_suffixes c-src/etags.c 549
ClassExample ruby-src/test.rb /^ class ClassExample$/
-ClassExample.singleton_class_method ruby-src/test.rb /^ def
ClassExample.singleton_class_method$/
+ClassExample.class_method ruby-src/test.rb /^ def
ClassExample.class_method$/
Clear/p ada-src/2ataspri.adb /^ procedure Clear (Cell : in out
TAS_Cell) is$/
Clear/p ada-src/2ataspri.ads /^ procedure Clear (Cell : in
out TAS_Cell)/
Cobol_help c-src/etags.c 558
@@ -939,7 +939,7 @@ Metags c-src/etags.c /^main (int argc, char **argv)$/
Mfail cp-src/fail.C /^main()$/
Mkai-test.pl perl-src/kai-test.pl /^package main;$/
ModuleExample ruby-src/test.rb /^module ModuleExample$/
-ModuleExample.singleton_module_method ruby-src/test.rb /^ def
ModuleExample.singleton_module_method$/
+ModuleExample.module_class_method ruby-src/test.rb /^ def
ModuleExample.module_class_method$/
More_Lisp_Bits c-src/emacs/src/lisp.h 801
MoveLayerAfter lua-src/allegro.lua /^function MoveLayerAfter (this_one)$/
MoveLayerBefore lua-src/allegro.lua /^function MoveLayerBefore
(this_one)$/
@@ -2620,10 +2620,10 @@ childDidExit objc-src/Subprocess.m /^-
childDidExit$/
chunks_free c-src/emacs/src/gmalloc.c 313
chunks_used c-src/emacs/src/gmalloc.c 311
cjava c-src/etags.c 2936
-class_method ruby-src/test.rb /^ def class_method$/
-class_method_equals= ruby-src/test.rb /^ def
class_method_equals=$/
-class_method_exclamation! ruby-src/test.rb /^ def
class_method_exclamation!$/
-class_method_question? ruby-src/test.rb /^ def
class_method_question?$/
+instance_method ruby-src/test.rb /^ def instance_method$/
+instance_method_equals= ruby-src/test.rb /^ def
instance_method_equals=$/
+instance_method_exclamation! ruby-src/test.rb /^ def
instance_method_exclamation!$/
+instance_method_question? ruby-src/test.rb /^ def
instance_method_question?$/
classifyLine php-src/lce_functions.php /^ function
classifyLine($line)$/
clear cp-src/conway.hpp /^ void clear(void) { alive = 0; }$/
clear-abbrev-table c-src/abbrev.c /^DEFUN ("clear-abbrev-table",
Fclear_abbrev_table, /
@@ -3450,7 +3450,7 @@ miti html-src/softwarelibero.html /^Sfatiamo
alcuni miti$/
modifier_names c-src/emacs/src/keyboard.c 6319
modifier_symbols c-src/emacs/src/keyboard.c 6327
modify_event_symbol c-src/emacs/src/keyboard.c /^modify_event_symbol
(ptrdiff_t symbol_num, int mod/
-module_method ruby-src/test.rb /^ def module_method$/
+module_instance_method ruby-src/test.rb /^ def
module_instance_method$/
more_aligned_int c.c 165
morecore_nolock c-src/emacs/src/gmalloc.c /^morecore_nolock
(size_t size)$/
morecore_recursing c-src/emacs/src/gmalloc.c 604
diff --git a/test/manual/etags/ETAGS.good_1 b/test/manual/etags/ETAGS.good_1
index 2ae4ec4..dac2091 100644
--- a/test/manual/etags/ETAGS.good_1
+++ b/test/manual/etags/ETAGS.good_1
@@ -2980,11 +2980,11 @@ class Configure(760,24879
ruby-src/test.rb,594
module ModuleExample1,0
class ClassExample2,21
- def class_method3,44
- def ClassExample.singleton_class_method6,116
- def class_method_exclamation!9,221
- def class_method_question?12,319
- def class_method_equals=class_method_equals=15,411
+ def instance_method3,44
+ def ClassExample.class_method6,116
+ def instance_method_exclamation!9,221
+ def instance_method_question?12,319
+ def instance_method_equals=class_method_equals=15,411
def `(18,499
def +(21,589
def [](24,637
@@ -2994,8 +2994,8 @@ module ModuleExample1,0
def <=(<=36,869
def <=>(<=>39,940
def ===(===42,987
- def module_method46,1048
- def ModuleExample.singleton_module_method49,1110
+ def module_instance_method46,1048
+ def ModuleExample.module_class_method49,1110
ruby-src/test1.ruby,37
class A1,0
diff --git a/test/manual/etags/ETAGS.good_2 b/test/manual/etags/ETAGS.good_2
index 3ec5b21..e5dbefb 100644
--- a/test/manual/etags/ETAGS.good_2
+++ b/test/manual/etags/ETAGS.good_2
@@ -3551,11 +3551,11 @@ class Configure(760,24879
ruby-src/test.rb,594
module ModuleExample1,0
class ClassExample2,21
- def class_method3,44
- def ClassExample.singleton_class_method6,116
- def class_method_exclamation!9,221
- def class_method_question?12,319
- def class_method_equals=class_method_equals=15,411
+ def instance_method3,44
+ def ClassExample.class_method6,116
+ def instance_method_exclamation!9,221
+ def instance_method_question?12,319
+ def instance_method_equals=class_method_equals=15,411
def `(18,499
def +(21,589
def [](24,637
@@ -3565,8 +3565,8 @@ module ModuleExample1,0
def <=(<=36,869
def <=>(<=>39,940
def ===(===42,987
- def module_method46,1048
- def ModuleExample.singleton_module_method49,1110
+ def module_instance_method46,1048
+ def ModuleExample.module_class_method49,1110
ruby-src/test1.ruby,37
class A1,0
diff --git a/test/manual/etags/ETAGS.good_3 b/test/manual/etags/ETAGS.good_3
index 43b84ee..804440a 100644
--- a/test/manual/etags/ETAGS.good_3
+++ b/test/manual/etags/ETAGS.good_3
@@ -3324,11 +3324,11 @@ class Configure(760,24879
ruby-src/test.rb,594
module ModuleExample1,0
class ClassExample2,21
- def class_method3,44
- def ClassExample.singleton_class_method6,116
- def class_method_exclamation!9,221
- def class_method_question?12,319
- def class_method_equals=class_method_equals=15,411
+ def instance_method3,44
+ def ClassExample.class_method6,116
+ def instance_method_exclamation!9,221
+ def instance_method_question?12,319
+ def instance_method_equals=class_method_equals=15,411
def `(18,499
def +(21,589
def [](24,637
@@ -3338,8 +3338,8 @@ module ModuleExample1,0
def <=(<=36,869
def <=>(<=>39,940
def ===(===42,987
- def module_method46,1048
- def ModuleExample.singleton_module_method49,1110
+ def module_instance_method46,1048
+ def ModuleExample.module_class_method49,1110
ruby-src/test1.ruby,37
class A1,0
diff --git a/test/manual/etags/ETAGS.good_4 b/test/manual/etags/ETAGS.good_4
index 434fe13..3b904eb 100644
--- a/test/manual/etags/ETAGS.good_4
+++ b/test/manual/etags/ETAGS.good_4
@@ -3144,11 +3144,11 @@ class Configure(760,24879
ruby-src/test.rb,594
module ModuleExample1,0
class ClassExample2,21
- def class_method3,44
- def ClassExample.singleton_class_method6,116
- def class_method_exclamation!9,221
- def class_method_question?12,319
- def class_method_equals=class_method_equals=15,411
+ def instance_method3,44
+ def ClassExample.class_method6,116
+ def instance_method_exclamation!9,221
+ def instance_method_question?12,319
+ def instance_method_equals=class_method_equals=15,411
def `(18,499
def +(21,589
def [](24,637
@@ -3158,8 +3158,8 @@ module ModuleExample1,0
def <=(<=36,869
def <=>(<=>39,940
def ===(===42,987
- def module_method46,1048
- def ModuleExample.singleton_module_method49,1110
+ def module_instance_method46,1048
+ def ModuleExample.module_class_method49,1110
ruby-src/test1.ruby,37
class A1,0
diff --git a/test/manual/etags/ETAGS.good_5 b/test/manual/etags/ETAGS.good_5
index 425e252..c3a2778 100644
--- a/test/manual/etags/ETAGS.good_5
+++ b/test/manual/etags/ETAGS.good_5
@@ -4059,11 +4059,11 @@ class Configure(760,24879
ruby-src/test.rb,594
module ModuleExample1,0
class ClassExample2,21
- def class_method3,44
- def ClassExample.singleton_class_method6,116
- def class_method_exclamation!9,221
- def class_method_question?12,319
- def class_method_equals=class_method_equals=15,411
+ def instance_method3,44
+ def ClassExample.class_method6,116
+ def instance_method_exclamation!9,221
+ def instance_method_question?12,319
+ def instance_method_equals=class_method_equals=15,411
def `(18,499
def +(21,589
def [](24,637
@@ -4073,8 +4073,8 @@ module ModuleExample1,0
def <=(<=36,869
def <=>(<=>39,940
def ===(===42,987
- def module_method46,1048
- def ModuleExample.singleton_module_method49,1110
+ def module_instance_method46,1048
+ def ModuleExample.module_class_method49,1110
ruby-src/test1.ruby,37
class A1,0
diff --git a/test/manual/etags/ETAGS.good_6 b/test/manual/etags/ETAGS.good_6
index 39522db..2014283 100644
--- a/test/manual/etags/ETAGS.good_6
+++ b/test/manual/etags/ETAGS.good_6
@@ -4059,11 +4059,11 @@ class Configure(760,24879
ruby-src/test.rb,594
module ModuleExample1,0
class ClassExample2,21
- def class_method3,44
- def ClassExample.singleton_class_method6,116
- def class_method_exclamation!9,221
- def class_method_question?12,319
- def class_method_equals=class_method_equals=15,411
+ def instance_method3,44
+ def ClassExample.class_method6,116
+ def instance_method_exclamation!9,221
+ def instance_method_question?12,319
+ def instance_method_equals=class_method_equals=15,411
def `(18,499
def +(21,589
def [](24,637
@@ -4073,8 +4073,8 @@ module ModuleExample1,0
def <=(<=36,869
def <=>(<=>39,940
def ===(===42,987
- def module_method46,1048
- def ModuleExample.singleton_module_method49,1110
+ def module_instance_method46,1048
+ def ModuleExample.module_class_method49,1110
ruby-src/test1.ruby,37
class A1,0
diff --git a/test/manual/etags/ruby-src/test.rb
b/test/manual/etags/ruby-src/test.rb
index 9254c5b..adb2cb1 100644
--- a/test/manual/etags/ruby-src/test.rb
+++ b/test/manual/etags/ruby-src/test.rb
@@ -1,19 +1,19 @@
module ModuleExample
class ClassExample
- def class_method
- puts "in class_method"
+ def instance_method
+ puts "in instane_method"
end
- def ClassExample.singleton_class_method
- puts "in singleton_class_method"
+ def ClassExample.class_method
+ puts "in class_method"
end
- def class_method_exclamation!
- puts "in class_method_exclamation!"
+ def instance_method_exclamation!
+ puts "in instance_method_exclamation!"
end
- def class_method_question?
- puts "in class_method_question?"
+ def instance_method_question?
+ puts "in instance_method_question?"
end
- def class_method_equals=
- puts "in class_method_equals="
+ def instance_method_equals=
+ puts "in instance_method_equals="
end
def `(command)
return "just testing a backquote override"
@@ -43,12 +43,16 @@ module ModuleExample
self == y
end
end
- def module_method
- puts "in module_method"
+ def module_instance_method
+ puts "in module_instance_method"
end
- def ModuleExample.singleton_module_method
- puts "in singleton_module_method"
+ def ModuleExample.module_class_method
+ puts "in module_class_method"
end
end
-ModuleExample::ClassExample.singleton_class_method
+ModuleExample::ClassExample.class_method
+
+# Local Variables:
+# ruby-indent-level: 4
+# End: