diff --git a/CONTRIBUTE b/CONTRIBUTE index e8bb95df45a..a5433e30d37 100644 --- a/CONTRIBUTE +++ b/CONTRIBUTE @@ -54,6 +54,12 @@ packages the patch's commit message and changes. To send just one such patch without additional remarks, you can use a command like 'git send-email --to=bug-gnu-emacs@gnu.org 0001-DESCRIPTION.patch'. +Once the cumulative amount of your submissions exceeds about 15 lines +of non-trivial changes, we will need you to assign to the FSF the +copyright for your contributions. Ask on emacs-devel@gnu.org, and we +will send you the necessary form together with the instructions to +fill and email it, in order to start this legal paperwork. + ** Issue tracker (a.k.a. "bug tracker") The Emacs issue tracker at https://debbugs.gnu.org lets you view bug diff --git a/ChangeLog.3 b/ChangeLog.3 index 235c8bb180e..e7f4d866326 100644 --- a/ChangeLog.3 +++ b/ChangeLog.3 @@ -1,3 +1,148 @@ +2019-04-11 Eli Zaretskii + + Improve documentation of 'read-command' + + * src/minibuf.c (Fread_command): Document the return value + when DEFAULT-VALUE is nil and the user enters nothing. + * doc/lispref/minibuf.texi (High-Level Completion): Document + the printed representation of a symbol whose name is empty. + (Bug#3522) + +2019-04-11 Eli Zaretskii + + Fix an outdated URL in a comment + + * src/emacs.c: Fix reference to Cocoa CoreFoundation Release + Notes. (Bug#35225) + +2019-04-11 Basil L. Contovounesios + + Backport: Fix comment-empty-lines docstring (bug#35152) + + * lisp/newcomment.el (comment-empty-lines): Consistently use US + commas in docstring. Fix indentation of and typo in custom :type. + + (cherry picked from commit 690c678fb6c1fb5b2f828f9bb90782bd0b01c399) + +2019-04-11 Alex Branham + + Backport: Update documentation for indent-relative functions + + * lisp/indent.el (indent-relative): Document what happens when there + is no previous nonblank line. + * doc/lispref/text.texi (Relative Indent): Document + indent-relative-first-indent-point instead of obsolete + indent-relative-maybe. Fix documentation of which argument from + 'indent-relative' is used. + + Bug#34858 + + (cherry picked from commit 10cd65878c741d2a22a1f2c36c54fcad4e516f72) + +2019-04-11 Noam Postavsky + + Update nxml-mode.texi: completion now gives xmlns="-!-" + + * doc/misc/nxml-mode.texi (Completion): As of 2016-01-16 "* lisp/nxml: + Use standard completion; it also works for company-mode", completing + an attribute when there is only one candidate inserts both quotes. + Update the example accordingly. + +2019-04-10 Eric Abrahamsen + + Note that choose-completion-string-functions funcs take four args + + * lisp/simple.el (choose-completion-string-functions): Functions in + this list actually need to accept four arguments, though the fourth + should be ignored. + +2019-04-10 Gemini Lasswell + + Address name conflicts in EIEIO documentation (bug#31660) + + * doc/misc/eieio.texi (Quick Start): Rename the class used in the + example from 'record' to 'person'. + (Building Classes): Advise user to check for name conflicts before + naming a class. Add a missing apostrophe. + (Making New Objects): Correct grammar. Rename the class used in the + example from 'record' to 'my-class'. + +2019-04-09 Mattias Engdegård + + Clarify the TESTFN argument to `alist-get' + + * lisp/subr.el (alist-get): + Rephrase the initial text to clarify the meaning of the TESTFN argument. + It's an equality predicate, not a look-up function (Bug#35206). + + (cherry picked from commit c81465580fe262f28ce47502c00f4afcbe3b8f8d) + +2019-04-08 Eli Zaretskii + + * src/editfns.c (Fnarrow_to_region): Doc fix. (Bug#35163) + +2019-04-06 Eli Zaretskii + + Fix doc strings of 'vc-version-diff' and 'vc-version-ediff' + + * lisp/vc/vc.el (vc-version-diff, vc-version-ediff): Describe + arguments in the doc strings. (Bug#35019) + +2019-04-06 Eli Zaretskii + + Improve documentation of set-window-start + + * doc/lispref/windows.texi (Window Start and End): + * src/window.c (Fset_window_start): Document that reliable + setting of a window start position requires to adjust point to + be visible. (Bug#34038) + +2019-04-06 Eli Zaretskii + + Improve documentation of window parameters + + * doc/lispref/windows.texi (Cyclic Window Ordering): Describe + the effect of the 'other-window' window parameter. + (Window Parameters): Improve the descriptions of window + parameters. Move the detailed description of the + 'quit-restore' window parameter from here... + (Quitting Windows): ...to here. (Bug#35063) + +2019-04-06 Eli Zaretskii + + Improve commentary in frame.el + + * lisp/frame.el: Improve commentary for display-* functions. + (Bug#35058) + +2019-04-06 Mauro Aranda + + Fix typo in a doc string + + * lisp/autorevert.el (global-auto-revert-mode): Fix a typo. + (Bug#35165) + +2019-03-20 Paul Eggert + + Say which regexp ranges should be avoided + + * doc/lispref/searching.texi (Regexp Special): Say that + regular expressions like "[a-m-z]" and "[[:alpha:]-~]" should + be avoided, for the same reason that regular expressions like + "+" and "*" should be avoided: POSIX says their behavior is + undefined, and they are confusing anyway. Also, explain + better what happens when the bound of a range is a raw 8-bit + byte; the old explanation appears to have been obsolete + anyway. Finally, say that ranges like "[\u00FF-\xFF]" that + mix non-ASCII characters and raw 8-bit bytes should be + avoided, since it’s not clear what they should mean. + +2019-03-20 Nicolas Petton + + * etc/AUTHORS: Update. + + * ; ChangeLog.3 update + 2019-03-20 Eli Zaretskii Improve indexing of the user manual @@ -64946,7 +65091,7 @@ This file records repository revisions from commit 9d56a21e6a696ad19ac65c4b405aeca44785884a (exclusive) to -commit 0f523deec1c1e9e2a5a3474f912aa2183d3fe33d (inclusive). +commit 85829363f728c410e33ffdc3839202977b2115cc (inclusive). See ChangeLog.1 for earlier changes. ;; Local Variables: diff --git a/build-aux/config.sub b/build-aux/config.sub index 3b4c7624b68..a44fd8ae908 100755 --- a/build-aux/config.sub +++ b/build-aux/config.sub @@ -822,7 +822,9 @@ case $basic_machine in cpu=m68k vendor=next case $os in - nextstep* ) + openstep*) + ;; + nextstep*) ;; ns2*) os=nextstep2 diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index 6c37fa92d6c..cfea336a9e5 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -1333,7 +1333,8 @@ is a string, @code{read-command} interns it before returning it. If it is a list, @code{read-command} interns the first element of this list. If @var{default} is @code{nil}, that means no default has been specified; then if the user enters null input, the return value is -@code{(intern "")}, that is, a symbol whose name is an empty string. +@code{(intern "")}, that is, a symbol whose name is an empty string, +and whose printed representation is @code{##} (@pxref{Symbol Type}). @example (read-command "Command name? ") diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 1ef836b8f94..500df1f8f0d 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -5156,8 +5156,11 @@ as in @code{json-parse-string}. @defun json-parse-string string &rest args This function parses the JSON value in @var{string}, which must be a -Lisp string. The argument @var{args} is a list of keyword/argument -pairs. The following keywords are accepted: +Lisp string. If @var{string} doesn't contain a valid JSON object, +this function signals the @code{json-parse-error} error. + +The argument @var{args} is a list of keyword/argument pairs. The +following keywords are accepted: @table @code @item :object-type @@ -5167,6 +5170,11 @@ key-value mappings of a JSON object. It can be either keys; @code{alist} to use alists with symbols as keys; or @code{plist} to use plists with keyword symbols as keys. +@item :array-type +The value decides which Lisp object to use for representing a JSON +array. It can be either @code{array}, the default, to use Lisp +arrays; or @code{list} to use lists. + @item :null-object The value decides which Lisp object to use to represent the JSON keyword @code{null}. It defaults to the symbol @code{:null}. @@ -5181,19 +5189,20 @@ keyword @code{false}. It defaults to the symbol @code{:false}. @defun json-parse-buffer &rest args This function reads the next JSON value from the current buffer, starting at point. It moves point to the position immediately after -the value if a value could be read and converted to Lisp; otherwise it -doesn't move point. The arguments @var{args} are interpreted as in -@code{json-parse-string}. +the value if contains a valid JSON object; otherwise it signals the +@code{json-parse-error} error and doesn't move point. The arguments +@var{args} are interpreted as in @code{json-parse-string}. @end defun @node JSONRPC @section JSONRPC communication @cindex JSON remote procedure call protocol +@cindex JSONRPC The @code{jsonrpc} library implements the @acronym{JSONRPC} specification, version 2.0, as it is described in @uref{http://www.jsonrpc.org/}. As the name suggests, JSONRPC is a -generic @code{Remote Procedure Call} protocol designed around +generic @dfn{Remote Procedure Call} protocol designed around @acronym{JSON} objects, which you can convert to and from Lisp objects (@pxref{Parsing JSON}). @@ -5212,81 +5221,96 @@ transport agnostic in that the concepts can be used within the same process, over sockets, over http, or in many various message passing environments." +@findex jsonrpc-connection To model this agnosticism, the @code{jsonrpc} library uses objects of -a @code{jsonrpc-connection} class, which represent a connection the +a @code{jsonrpc-connection} class, which represent a connection to a remote JSON endpoint (for details on Emacs's object system, @pxref{Top,EIEIO,,eieio,EIEIO}). In modern object-oriented parlance, -this class is ``abstract'', i.e. the actual class of a useful -connection object used is always a subclass of it. Nevertheless, we -can define two distinct API's around the @code{jsonrpc-connection} -class: +this class is ``abstract'', i.e.@: the actual class of a useful +connection object is always a subclass of @code{jsonrpc-connection}. +Nevertheless, we can define two distinct APIs around the +@code{jsonrpc-connection} class: +@cindex JSONRPC application interfaces @enumerate @item A user interface for building JSONRPC applications +@findex :request-dispatcher +@findex :notification-dispatcher +@findex jsonrpc-notify +@findex jsonrpc-request +@findex jsonrpc-async-request In this scenario, the JSONRPC application selects a concrete subclass of @code{jsonrpc-connection}, and proceeds to create objects of that subclass using @code{make-instance}. To initiate a contact to the remote endpoint, the JSONRPC application passes this object to the -functions @code{jsonrpc-notify'}, @code{jsonrpc-request} and +functions @code{jsonrpc-notify}, @code{jsonrpc-request}, and/or @code{jsonrpc-async-request}. For handling remotely initiated contacts, which generally come in asynchronously, the instantiation should include @code{:request-dispatcher} and @code{:notification-dispatcher} initargs, which are both functions of 3 arguments: the connection object; a symbol naming the JSONRPC method -invoked remotely; and a JSONRPC "params" object. +invoked remotely; and a JSONRPC @code{params} object. +@findex jsonrpc-error The function passed as @code{:request-dispatcher} is responsible for handling the remote endpoint's requests, which expect a reply from the local endpoint (in this case, the program you're building). Inside -that function, you may either return locally (normally) or non-locally -(error). A local return value must be a Lisp object serializable as -JSON (@pxref{Parsing JSON}). This determines a success response, and -the object is forwarded to the server as the JSONRPC "result" object. -A non-local return, achieved by calling the function -@code{jsonrpc-error}, causes an error response to be sent to the -server. The details of the accompanying JSONRPC "error" are filled -out with whatever was passed to @code{jsonrpc-error}. A non-local -return triggered by an unexpected error of any other type also causes -an error response to be sent (unless you have set -@code{debug-on-error}, in which case this should land you in the -debugger, @pxref{Error Debugging}). +that function, you may either return locally (a normal return) or +non-locally (an error return). A local return value must be a Lisp +object that can be serialized as JSON (@pxref{Parsing JSON}). This +determines a success response, and the object is forwarded to the +server as the JSONRPC @code{result} object. A non-local return, +achieved by calling the function @code{jsonrpc-error}, causes an error +response to be sent to the server. The details of the accompanying +JSONRPC @code{error} are filled out with whatever was passed to +@code{jsonrpc-error}. A non-local return triggered by an unexpected +error of any other type also causes an error response to be sent +(unless you have set @code{debug-on-error}, in which case this calls +the Lisp debugger, @pxref{Error Debugging}). @item A inheritance interface for building JSONRPC transport implementations In this scenario, @code{jsonrpc-connection} is subclassed to implement a different underlying transport strategy (for details on how to -subclass, @pxref{Inheritance,Inheritance,,eieio}). Users of the +subclass, see @ref{Inheritance,Inheritance,,eieio}.). Users of the application-building interface can then instantiate objects of this concrete class (using the @code{make-instance} function) and connect to JSONRPC endpoints using that strategy. This API has mandatory and optional parts. +@findex jsonrpc-connection-send To allow its users to initiate JSONRPC contacts (notifications or -requests) or reply to endpoint requests, the method -@code{jsonrpc-connection-send} must be implemented for the subclass. +requests) or reply to endpoint requests, the subclass must have an +implementation of the @code{jsonrpc-connection-send} method. +@findex jsonrpc-connection-receive Likewise, for handling the three types of remote contacts (requests, -notifications and responses to local requests) the transport +notifications, and responses to local requests), the transport implementation must arrange for the function @code{jsonrpc-connection-receive} to be called after noticing a new JSONRPC message on the wire (whatever that "wire" may be). +@findex jsonrpc-shutdown +@findex jsonrpc-running-p Finally, and optionally, the @code{jsonrpc-connection} subclass should -implement @code{jsonrpc-shutdown} and @code{jsonrpc-running-p} if -these concepts apply to the transport. If they do, then any system -resources (e.g. processes, timers, etc..) used listen for messages on -the wire should be released in @code{jsonrpc-shutdown}, i.e. they -should only be needed while @code{jsonrpc-running-p} is non-nil. +implement the @code{jsonrpc-shutdown} and @code{jsonrpc-running-p} +methods if these concepts apply to the transport. If they do, then +any system resources (e.g.@: processes, timers, etc.) used to listen for +messages on the wire should be released in @code{jsonrpc-shutdown}, +i.e.@: they should only be needed while @code{jsonrpc-running-p} is +non-nil. @end enumerate @node Process-based JSONRPC connections @subsection Process-based JSONRPC connections +@cindex JSONRPC process-based connections -For convenience, the @code{jsonrpc} library comes built-in with a +@findex jsonrpc-process-connection +For convenience, the @code{jsonrpc} library comes with a built-in @code{jsonrpc-process-connection} transport implementation that can talk to local subprocesses (using the standard input and standard output); or TCP hosts (using sockets); or any other remote endpoint @@ -5301,6 +5325,7 @@ JSONRPC, see the @uref{https://microsoft.github.io/language-server-protocol/specification, Language Server Protocol}. +@cindex JSONRPC connection initargs Along with the mandatory @code{:request-dispatcher} and @code{:notification-dispatcher} initargs, users of the @code{jsonrpc-process-connection} class should pass the following @@ -5309,29 +5334,32 @@ initargs as keyword-value pairs to @code{make-instance}: @table @code @item :process Value must be a live process object or a function of no arguments -producing one such object. If passed a process object, that is -expected to contain an pre-established connection; otherwise, the +producing one such object. If passed a process object, the object is +expected to contain a pre-established connection; otherwise, the function is called immediately after the object is made. @item :on-shutdown Value must be a function of a single argument, the @code{jsonrpc-process-connection} object. The function is called after the underlying process object has been deleted (either -deliberately by @code{jsonrpc-shutdown} or unexpectedly, because of +deliberately by @code{jsonrpc-shutdown}, or unexpectedly, because of some external cause). @end table @node JSONRPC JSON object format -@subsection JSON object format +@subsection JSONRPC JSON object format +@cindex JSONRPC object format -JSON objects are exchanged as Lisp plists (@pxref{Parsing JSON}): -JSON-compatible plists are handed to the dispatcher functions and, -likewise, JSON-compatible plists should be given to -@code{jsonrpc-notify}, @code{jsonrpc-request} and +JSONRPC JSON objects are exchanged as Lisp plists (@pxref{Property +Lists}): JSON-compatible plists are handed to the dispatcher functions +and, likewise, JSON-compatible plists should be given to +@code{jsonrpc-notify}, @code{jsonrpc-request}, and @code{jsonrpc-async-request}. -To facilitate handling plists, this library make liberal use of -@code{cl-lib} library and suggests (but doesn't force) its clients to +@findex jsonrpc-lambda +To facilitate handling plists, this library makes liberal use of +@code{cl-lib} library (@pxref{Top,cl-lib,,cl,Common Lisp Extensions +for GNU Emacs Lisp}) and suggests (but doesn't force) its clients to do the same. A macro @code{jsonrpc-lambda} can be used to create a lambda for destructuring a JSON-object like in this example: @@ -5347,7 +5375,8 @@ lambda for destructuring a JSON-object like in this example: @end example @node JSONRPC deferred requests -@subsection Deferred requests +@subsection Deferred JSONRPC requests +@cindex JSONRPC deferred requests In many @acronym{RPC} situations, synchronization between the two communicating endpoints is a matter of correctly designing the RPC @@ -5359,6 +5388,7 @@ is still uncertainty about the state of the remote endpoint. Furthermore, acting on these events may only sometimes demand synchronization, depending on the event's specific nature. +@findex :deferred@r{, JSONRPC keyword} The @code{:deferred} keyword argument to @code{jsonrpc-request} and @code{jsonrpc-async-request} is designed to let the caller indicate that the specific request needs synchronization and its actual @@ -5369,9 +5399,10 @@ isn't sent immediately, @code{jsonrpc} will make renewed efforts to send it at certain key times during communication, such as when receiving or sending other messages to the endpoint. +@findex jsonrpc-connection-ready-p Before any attempt to send the request, the application-specific -conditions are checked. Since the @code{jsonrpc} library can't known -what these conditions are, the programmer may use the +conditions are checked. Since the @code{jsonrpc} library can't know +what these conditions are, the program can use the @code{jsonrpc-connection-ready-p} generic function (@pxref{Generic Functions}) to specify them. The default method for this function returns @code{t}, but you can add overriding methods that return diff --git a/doc/misc/nxml-mode.texi b/doc/misc/nxml-mode.texi index edab900652d..2b2c241a6e4 100644 --- a/doc/misc/nxml-mode.texi +++ b/doc/misc/nxml-mode.texi @@ -250,7 +250,7 @@ xml:lang xmlns If you input @kbd{xmlns}, the result will be: @example -\^^M' is replaced by a single space. % @@ -1123,16 +1131,6 @@ \fi \fi -\newif\ifpdforxetex -\pdforxetexfalse -\ifpdf - \pdforxetextrue -\fi -\ifx\XeTeXrevision\thisisundefined\else - \pdforxetextrue -\fi - - % PDF uses PostScript string constants for the names of xref targets, % for display in the outlines, and in other places. Thus, we have to % double any backslashes. Otherwise, a name like "\node" will be @@ -2846,7 +2844,7 @@ % @t, explicit typewriter. \def\t#1{% - {\tt \plainfrenchspacing #1}% + {\tt \rawbackslash \plainfrenchspacing #1}% \null } @@ -2873,6 +2871,7 @@ % Turn off hyphenation. \nohyphenation % + \rawbackslash \plainfrenchspacing #1% }% @@ -3113,7 +3112,7 @@ % So now @email is just like @uref, unless we are pdf. % %\def\email#1{\angleleft{\tt #1}\angleright} -\ifpdforxetex +\ifpdf \def\email#1{\doemail#1,,\finish} \def\doemail#1,#2,#3\finish{\begingroup \unsepspaces @@ -3123,7 +3122,18 @@ \endlink \endgroup} \else - \let\email=\uref + \ifx\XeTeXrevision\thisisundefined + \let\email=\uref + \else + \def\email#1{\doemail#1,,\finish} + \def\doemail#1,#2,#3\finish{\begingroup + \unsepspaces + \pdfurl{mailto:#1}% + \setbox0 = \hbox{\ignorespaces #2}% + \ifdim\wd0>0pt\unhbox0\else\code{#1}\fi + \endlink + \endgroup} + \fi \fi % @kbdinputstyle -- arg is `distinct' (@kbd uses slanted tty font always), @@ -4657,6 +4667,19 @@ } } +% We have this subroutine so that we can handle at least some @value's +% properly in indexes (we call \makevalueexpandable in \indexdummies). +% The command has to be fully expandable (if the variable is set), since +% the result winds up in the index file. This means that if the +% variable's value contains other Texinfo commands, it's almost certain +% it will fail (although perhaps we could fix that with sufficient work +% to do a one-level expansion on the result, instead of complete). +% +% Unfortunately, this has the consequence that when _ is in the *value* +% of an @set, it does not print properly in the roman fonts (get the cmr +% dot accent at position 126 instead). No fix comes to mind, and it's +% been this way since 2003 or earlier, so just ignore it. +% \def\expandablevalue#1{% \expandafter\ifx\csname SET#1\endcsname\relax {[No value for ``#1'']}% @@ -4685,7 +4708,7 @@ % if possible, otherwise sort late. \def\indexnofontsvalue#1{% \expandafter\ifx\csname SET#1\endcsname\relax - ZZZZZZZ% + ZZZZZZZ \else \csname SET#1\endcsname \fi @@ -4835,8 +4858,23 @@ \def\docodeindexxxx #1{\doind{\indexname}{\code{#1}}} -% Used for the aux, toc and index files to prevent expansion of Texinfo -% commands. +% Used when writing an index entry out to an index file to prevent +% expansion of Texinfo commands that can appear in an index entry. +% +\def\indexdummies{% + \escapechar = `\\ % use backslash in output files. + \definedummyletter\@% + \definedummyletter\ % + % + % For texindex which always views { and } as separators. + \def\{{\lbracechar{}}% + \def\}{\rbracechar{}}% + % + % Do the redefinitions. + \definedummies +} + +% Used for the aux and toc files, where @ is the escape character. % \def\atdummies{% \definedummyletter\@% @@ -4866,7 +4904,8 @@ \def\definedummyletter#1{\def#1{\string#1}}% \let\definedummyaccent\definedummyletter -% Called from \atdummies to prevent the expansion of commands. +% Called from \indexdummies and \atdummies, to effectively prevent +% the expansion of commands. % \def\definedummies{% % @@ -5031,9 +5070,11 @@ \commondummyword\xref } +% This does nothing, but for a time it was recommended to use +% \usebracesinindexestrue to be able to use braces in index entries. + \let\indexlbrace\relax \let\indexrbrace\relax -\let\indexatchar\relax {\catcode`\@=0 \catcode`\\=13 @@ -5067,8 +5108,10 @@ } \gdef\indexnonalnumreappear{% + \useindexbackslash \let-\normaldash \let<\normalless + \def\@{@}% } } @@ -5179,6 +5222,8 @@ +\let\SETmarginindex=\relax % put index entries in margin (undocumented)? + % #1 is the index name, #2 is the entry text. \def\doind#1#2{% \iflinks @@ -5210,6 +5255,13 @@ \fi} \def\indexisfl{fl} +% Output \ as {\indexbackslash}, because \ is an escape character in +% the index files. +\let\indexbackslash=\relax +{\catcode`\@=0 \catcode`\\=\active + @gdef@useindexbackslash{@def\{{@indexbackslash}}} +} + % Definition for writing index entry sort key. { \catcode`\-=13 @@ -5221,25 +5273,14 @@ \xdef\indexsortkey{#1}\endgroup} } -\def\indexwriteseealso#1{ - \gdef\pagenumbertext{@seealso{#1}}% -} - -% The default definitions -\def\sortas#1{}% -\def\seealso#1{\i{\putwordSeeAlso}\ #1}% for sorted index file only -\def\putwordSeeAlso{see also} - % Given index entry text like "aaa @subentry bbb @sortas{ZZZ}": % * Set \bracedtext to "{aaa}{bbb}" % * Set \fullindexsortkey to "aaa @subentry ZZZ" -% * If @seealso occurs, set \pagenumbertext % \def\splitindexentry#1{% \gdef\fullindexsortkey{}% \xdef\bracedtext{}% \def\sep{}% - \def\seealso##1{}% \expandafter\doindexsegment#1\subentry\finish\subentry } @@ -5251,6 +5292,7 @@ % % Fully expand the segment, throwing away any @sortas directives, and % trim spaces. + \def\sortas##1{}% \edef\trimmed{\segment}% \edef\trimmed{\expandafter\eatspaces\expandafter{\trimmed}}% % @@ -5260,20 +5302,16 @@ % font commands turned off. \bgroup \let\sortas\indexwritesortas - \let\seealso\indexwriteseealso \indexnofonts % The braces around the commands are recognized by texindex. \def\lbracechar{{\indexlbrace}}% \def\rbracechar{{\indexrbrace}}% \let\{=\lbracechar \let\}=\rbracechar - \def\@{{\indexatchar}}% - \def\atchar##1{\@}% % \let\indexsortkey\empty - \global\let\pagenumbertext\empty % Execute the segment and throw away the typeset output. This executes - % any @sortas or @seealso commands in this segment. + % any @sortas commands in this segment. \setbox\dummybox = \hbox{\segment}% \ifx\indexsortkey\empty{% \indexnonalnumdisappear @@ -5294,20 +5332,21 @@ \fi } \def\isfinish{\finish}% -\newbox\dummybox % used above \let\subentry\relax % Write the entry in \toks0 to the index file. % \def\doindwrite{% - \maybemarginindex + % Put the index entry in the margin if desired. + \ifx\SETmarginindex\relax\else + \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \the\toks0}}% + \fi % - \atdummies - % - % For texindex which always views { and } as separators. - \def\{{\lbracechar{}}% - \def\}{\rbracechar{}}% + % Remember, we are within a group. + \indexdummies % Must do this here, since \bf, etc expand at this stage + \useindexbackslash % \indexbackslash isn't defined now so it will be output + % as is; and it will print as backslash. % % Split the entry into primary entry and any subentries, and get the index % sort key. @@ -5321,21 +5360,11 @@ % \edef\temp{% \write\writeto{% - \string\entry{\fullindexsortkey}% - {\ifx\pagenumbertext\empty\noexpand\folio\else\pagenumbertext\fi}% - \bracedtext}% + \string\entry{\fullindexsortkey}{\noexpand\folio}\bracedtext}% }% \temp } - -% Put the index entry in the margin if desired (undocumented). -\def\maybemarginindex{% - \ifx\SETmarginindex\relax\else - \insert\margin{\hbox{\vrule height8pt depth3pt width0pt \relax\indextext}}% - \fi -} -\let\SETmarginindex=\relax - +\newbox\dummybox % used above % Take care of unwanted page breaks/skips around a whatsit: % @@ -5423,14 +5452,9 @@ % \entry {topic}{pagelist} % for a topic that is used without subtopics % \primary {topic} -% \entry {topic}{} % for the beginning of a topic that is used with subtopics % \secondary {subtopic}{pagelist} % for each subtopic. -% \secondary {subtopic}{} -% for a subtopic with sub-subtopics -% \tertiary {subtopic}{subsubtopic}{pagelist} -% for each sub-subtopic. % Define the user-accessible indexing commands % @findex, @vindex, @kindex, @cindex. @@ -5455,10 +5479,14 @@ \plainfrenchspacing \everypar = {}% don't want the \kern\-parindent from indentation suppression. % + % See if the index file exists and is nonempty. + % Change catcode of @ here so that if the index file contains + % \initial {@} + % as its first line, TeX doesn't complain about mismatched braces + % (because it thinks @} is a control sequence). + \catcode`\@ = 12 % See comment in \requireopenindexfile. \def\indexname{#1}\ifx\indexname\indexisfl\def\indexname{f1}\fi - % - % See if the index file exists and is nonempty. \openin 1 \jobname.\indexname s \ifeof 1 % \enddoublecolumns gets confused if there is no text in the index, @@ -5468,6 +5496,8 @@ \putwordIndexNonexistent \typeout{No file \jobname.\indexname s.}% \else + \catcode`\\ = 0 + % % If the index file exists but is empty, then \openin leaves \ifeof % false. We have to make TeX try to read something from the file, so % it can discover if there is anything in it. @@ -5475,27 +5505,47 @@ \ifeof 1 \putwordIndexIsEmpty \else - \expandafter\printindexzz\thisline\relax\relax\finish% + % Index files are almost Texinfo source, but we use \ as the escape + % character. It would be better to use @, but that's too big a change + % to make right now. + \def\indexbackslash{\ttbackslash}% + \let\indexlbrace\{ % Likewise, set these sequences for braces + \let\indexrbrace\} % used in the sort key. + \begindoublecolumns + \let\dotheinsertentrybox\dotheinsertentryboxwithpenalty + % + % Read input from the index file line by line. + \loopdo + \ifeof1 \else + \read 1 to \nextline + \fi + % + \indexinputprocessing + \thisline + % + \ifeof1\else + \let\thisline\nextline + \repeat + %% + \enddoublecolumns \fi \fi \closein 1 \endgroup} +\def\loopdo#1\repeat{\def\body{#1}\loopdoxxx} +\def\loopdoxxx{\let\next=\relax\body\let\next=\loopdoxxx\fi\next} -% If the index file starts with a backslash, forgo reading the index -% file altogether. If somebody upgrades texinfo.tex they may still have -% old index files using \ as the escape character. Reading this would -% at best lead to typesetting garbage, at worst a TeX syntax error. -\def\printindexzz#1#2\finish{% - % NB this won't work if the index file starts with a group... - \uccode`\~=`\\ \uppercase{\if\noexpand~}\noexpand#1 - \message{skipping sorted index file}% - (Skipped sorted index file in obsolete format) +\def\indexinputprocessing{% + \ifeof1 + \let\firsttoken\relax \else - \begindoublecolumns - \input \jobname.\indexname s - \enddoublecolumns + \edef\act{\gdef\noexpand\firsttoken{\getfirsttoken\nextline}}% + \act \fi } +\def\getfirsttoken#1{\expandafter\getfirsttokenx#1\endfirsttoken} +\long\def\getfirsttokenx#1#2\endfirsttoken{\noexpand#1} + % These macros are used by the sorted index file itself. % Change them to control the appearance of the index. @@ -5504,18 +5554,12 @@ \catcode`\|=13 \catcode`\<=13 \catcode`\>=13 \catcode`\+=13 \catcode`\"=13 \catcode`\$=3 \gdef\initialglyphs{% - % special control sequences used in the index sort key - \let\indexlbrace\{% - \let\indexrbrace\}% - \let\indexatchar\@% - % % Some changes for non-alphabetic characters. Using the glyphs from the % math fonts looks more consistent than the typewriter font used elsewhere % for these characters. - \uccode`\~=`\\ \uppercase{\def~{\math{\backslash}}} + \def\indexbackslash{\math{\backslash}}% + \let\\=\indexbackslash % - % In case @\ is used for backslash - \uppercase{\let\\=~} % Can't get bold backslash so don't use bold forward slash \catcode`\/=13 \def/{{\secrmnotbold \normalslash}}% @@ -5574,6 +5618,12 @@ % \def\entry{% \begingroup + % + % For pdfTeX and XeTeX. + % The redefinition of \domark stops marks being added in \pdflink to + % preserve coloured links across page boundaries. Otherwise the marks + % would get in the way of \lastbox in \insertentrybox. + \let\domark\relax % % Start a new paragraph if necessary, so our assignments below can't % affect previous text. @@ -5607,31 +5657,35 @@ \gdef\finishentry#1{% \egroup % end box A \dimen@ = \wd\boxA % Length of text of entry - \global\setbox\boxA=\hbox\bgroup - \unhbox\boxA - % #1 is the page number. + \global\setbox\boxA=\hbox\bgroup\unhbox\boxA + % #1 is the page number. + % + % Get the width of the page numbers, and only use + % leaders if they are present. + \global\setbox\boxB = \hbox{#1}% + \ifdim\wd\boxB = 0pt + \null\nobreak\hfill\ % + \else % - % Get the width of the page numbers, and only use - % leaders if they are present. - \global\setbox\boxB = \hbox{#1}% - \ifdim\wd\boxB = 0pt - \null\nobreak\hfill\ % + \null\nobreak\indexdotfill % Have leaders before the page number. + % + \ifpdf + \pdfgettoks#1.% + \hskip\skip\thinshrinkable\the\toksA \else - % - \null\nobreak\indexdotfill % Have leaders before the page number. - % - \ifpdforxetex + \ifx\XeTeXrevision\thisisundefined + \hskip\skip\thinshrinkable #1% + \else \pdfgettoks#1.% \hskip\skip\thinshrinkable\the\toksA - \else - \hskip\skip\thinshrinkable #1% \fi \fi + \fi \egroup % end \boxA \ifdim\wd\boxB = 0pt - \noindent\unhbox\boxA\par - \nobreak - \else\bgroup + \global\setbox\entrybox=\vbox{\unhbox\boxA}% + \else + \global\setbox\entrybox=\vbox\bgroup % We want the text of the entries to be aligned to the left, and the % page numbers to be aligned to the right. % @@ -5697,11 +5751,55 @@ \egroup % The \vbox \fi \endgroup + \dotheinsertentrybox }} \newskip\thinshrinkable \skip\thinshrinkable=.15em minus .15em +\newbox\entrybox +\def\insertentrybox{% + \ourunvbox\entrybox +} + +% default definition +\let\dotheinsertentrybox\insertentrybox + +% Use \lastbox to take apart vbox box by box, and add each sub-box +% to the current vertical list. +\def\ourunvbox#1{% +\bgroup % for local binding of \delayedbox + % Remove the last box from box #1 + \global\setbox#1=\vbox{% + \unvbox#1% + \unskip % remove any glue + \unpenalty + \global\setbox\interbox=\lastbox + }% + \setbox\delayedbox=\box\interbox + \ifdim\ht#1=0pt\else + \ourunvbox#1 % Repeat on what's left of the box + \nobreak + \fi + \box\delayedbox +\egroup +} +\newbox\delayedbox +\newbox\interbox + +% Used from \printindex. \firsttoken should be the first token +% after the \entry. If it's not another \entry, we are at the last +% line of a group of index entries, so insert a penalty to discourage +% widowed index entries. +\def\dotheinsertentryboxwithpenalty{% + \ifx\firsttoken\isentry + \else + \penalty 9000 + \fi + \insertentrybox +} +\def\isentry{\entry}% + % Like plain.tex's \dotfill, except uses up at least 1 em. % The filll stretch here overpowers both the fil and fill stretch to push % the page number to the right. @@ -5711,15 +5809,24 @@ \def\primary #1{\line{#1\hfil}} -\def\secondary{\indententry{0.5cm}} -\def\tertiary{\indententry{1cm}} - -\def\indententry#1#2#3{% - \bgroup - \leftskip=#1 - \entry{#2}{#3}% - \egroup -} +\newskip\secondaryindent \secondaryindent=0.5cm +\def\secondary#1#2{{% + \parfillskip=0in + \parskip=0in + \hangindent=1in + \hangafter=1 + \noindent\hskip\secondaryindent\hbox{#1}\indexdotfill + \ifpdf + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \else + \ifx\XeTeXrevision\thisisundefined + #2 + \else + \pdfgettoks#2.\ \the\toksA % The page number ends the paragraph. + \fi + \fi + \par +}} % Define two-column mode, which we use to typeset indexes. % Adapted from the TeXbook, page 416, which is to say, @@ -5737,6 +5844,17 @@ \output = {% \savetopmark % + % Here is a possibility not foreseen in manmac: if we accumulate a + % whole lot of material, we might end up calling this \output + % routine twice in a row (see the doublecol-lose test, which is + % essentially a couple of indexes with @setchapternewpage off). In + % that case we just ship out what is in \partialpage with the normal + % output routine. Generally, \partialpage will be empty when this + % runs and this will be a no-op. See the indexspread.tex test case. + \ifvoid\partialpage \else + \onepageout{\pagecontents\partialpage}% + \fi + % \global\setbox\partialpage = \vbox{% % Unvbox the main output page. \unvbox\PAGE @@ -6016,9 +6134,11 @@ % @raisesections: treat @section as chapter, @subsection as section, etc. \def\raisesections{\global\advance\secbase by -1} +\let\up=\raisesections % original BFox name % @lowersections: treat @chapter as section, @section as subsection, etc. \def\lowersections{\global\advance\secbase by 1} +\let\down=\lowersections % original BFox name % we only have subsub. \chardef\maxseclevel = 3 @@ -6670,8 +6790,13 @@ % 1 and 2 (the page numbers aren't printed), and so are the first % two pages of the document. Thus, we'd have two destinations named % `1', and two named `2'. - \ifpdforxetex + \ifpdf \global\pdfmakepagedesttrue + \else + \ifx\XeTeXrevision\thisisundefined + \else + \global\pdfmakepagedesttrue + \fi \fi } @@ -7034,7 +7159,11 @@ % @cartouche ... @end cartouche: draw rectangle w/rounded corners around % environment contents. - +\font\circle=lcircle10 +\newdimen\circthick +\newdimen\cartouter\newdimen\cartinner +\newskip\normbskip\newskip\normpskip\newskip\normlskip +\circthick=\fontdimen8\circle % \def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth \def\ctr{{\hskip 6pt\circle\char'010}} @@ -7049,18 +7178,7 @@ % \newskip\lskip\newskip\rskip -% only require the font if @cartouche is actually used -\def\cartouchefontdefs{% - \font\circle=lcircle10\relax - \circthick=\fontdimen8\circle -} -\newdimen\circthick -\newdimen\cartouter\newdimen\cartinner -\newskip\normbskip\newskip\normpskip\newskip\normlskip - - \envdef\cartouche{% - \cartouchefontdefs \ifhmode\par\fi % can't be in the midst of a paragraph. \startsavinginserts \lskip=\leftskip \rskip=\rightskip @@ -7932,18 +8050,36 @@ } \fi +% alias because \c means cedilla in @tex or @math +\let\texinfoc=\c + +\newcount\savedcatcodeone +\newcount\savedcatcodetwo + % Used at the time of macro expansion. % Argument is macro body with arguments substituted \def\scanmacro#1{% \newlinechar`\^^M \def\xeatspaces{\eatspaces}% % - % Process the macro body under the current catcode regime. - \scantokens{#1@comment}% + % Temporarily undo catcode changes of \printindex. Set catcode of @ to + % 0 so that @-commands in macro expansions aren't printed literally when + % formatting an index file, where \ is used as the escape character. + \savedcatcodeone=\catcode`\@ + \savedcatcodetwo=\catcode`\\ + \catcode`\@=0 + \catcode`\\=\active % - % The \comment is to remove the \newlinechar added by \scantokens, and - % can be noticed by \parsearg. Note \c isn't used because this means cedilla - % in math mode. + % Process the macro body under the current catcode regime. + \scantokens{#1@texinfoc}% + % + \catcode`\@=\savedcatcodeone + \catcode`\\=\savedcatcodetwo + % + % The \texinfoc is to remove the \newlinechar added by \scantokens, and + % can be noticed by \parsearg. + % We avoid surrounding the call to \scantokens with \bgroup and \egroup + % to allow macros to open or close groups themselves. } % Used for copying and captions @@ -8044,14 +8180,12 @@ \def\macroargctxt{% \scanctxt \catcode`\ =\active - \catcode`\@=\other \catcode`\^^M=\other \catcode`\\=\active } \def\macrolineargctxt{% used for whole-line arguments without braces \scanctxt - \catcode`\@=\other \catcode`\{=\other \catcode`\}=\other } @@ -8615,21 +8749,9 @@ % also remove a trailing comma, in case of something like this: % @node Help-Cross, , , Cross-refs \def\donode#1 ,#2\finishnodeparse{\dodonode #1,\finishnodeparse} -\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}\omittopnode} - -% Used so that the @top node doesn't have to be wrapped in an @ifnottex -% conditional. -% \doignore goes to more effort to skip nested conditionals but we don't need -% that here. -\def\omittopnode{% - \ifx\lastnode\wordTop - \expandafter\ignorenode\fi -} -\def\wordTop{Top} - -% Divert output to a box that is not output until the next @node command. -\def\ignorenode{\setbox\dummybox\vbox\bgroup\def\node{\egroup\node}} +\def\dodonode#1,#2\finishnodeparse{\gdef\lastnode{#1}} +\let\nwnode=\node \let\lastnode=\empty % Write a cross-reference definition for the current node. #1 is the @@ -9104,6 +9226,19 @@ \catcode`\^^]=\other \catcode`\^^^=\other \catcode`\^^_=\other + % It was suggested to set the catcode of ^ to 7, which would allow ^^e4 etc. + % in xref tags, i.e., node names. But since ^^e4 notation isn't + % supported in the main text, it doesn't seem desirable. Furthermore, + % that is not enough: for node names that actually contain a ^ + % character, we would end up writing a line like this: 'xrdef {'hat + % b-title}{'hat b} and \xrdef does a \csname...\endcsname on the first + % argument, and \hat is not an expandable control sequence. It could + % all be worked out, but why? Either we support ^^ or we don't. + % + % The other change necessary for this was to define \auxhat: + % \def\auxhat{\def^{'hat }}% extra space so ok if followed by letter + % and then to call \auxhat in \setq. + % \catcode`\^=\other % % Special characters. Should be turned off anyway, but... @@ -9121,7 +9256,14 @@ \catcode`\%=\other \catcode`+=\other % avoid \+ for paranoia even though we've turned it off % - \catcode`\\=\active + % This is to support \ in node names and titles, since the \ + % characters end up in a \csname. It's easier than + % leaving it active and making its active definition an actual \ + % character. What I don't understand is why it works in the *value* + % of the xrdef. Seems like it should be a catcode12 \, and that + % should not typeset properly. But it works, so I'm moving on for + % now. --karl, 15jan04. + \catcode`\\=\other % % @ is our escape character in .aux files, and we need braces. \catcode`\{=1 @@ -11392,9 +11534,11 @@ % \backslashcurfont outputs one backslash character in current font, % as in \char`\\. \global\chardef\backslashcurfont=`\\ +\global\let\rawbackslashxx=\backslashcurfont % let existing .??s files work -% \realbackslash is an actual character `\' with catcode other. -{\catcode`\\=\other @gdef@realbackslash{\}} +% \realbackslash is an actual character `\' with catcode other, and +% \doublebackslash is two of them (for the pdf outlines). +{\catcode`\\=\other @gdef@realbackslash{\} @gdef@doublebackslash{\\}} % In Texinfo, backslash is an active character; it prints the backslash % in fixed width font. @@ -11412,8 +11556,10 @@ @def@ttbackslash{{@tt @ifmmode @mathchar29020 @else @backslashcurfont @fi}} @let@backslashchar = @ttbackslash % @backslashchar{} is for user documents. +% \rawbackslash defines an active \ to do \backslashcurfont. % \otherbackslash defines an active \ to be a literal `\' character with -% catcode other. +% catcode other. We switch back and forth between these. +@gdef@rawbackslash{@let\=@backslashcurfont} @gdef@otherbackslash{@let\=@realbackslash} % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of @@ -11485,7 +11631,7 @@ @ifx\@eatinput @let\ = @ttbackslash @fi @catcode13=5 % regular end of line @enableemergencynewline - @let@c=@comment + @let@c=@texinfoc @let@parsearg@originalparsearg % Also turn back on active characters that might appear in the input % file name, in case not using a pre-dumped format. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index e376fc7495e..3dfd5224ecd 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -2,9 +2,8 @@ @setfilename ../../info/tramp.info @c %**start of header @include docstyle.texi -@c In the Tramp repository, the version number is auto-frobbed from -@c configure.ac, so you should edit that file and run -@c "autoconf && ./configure" to change the version number. +@c In the Tramp GIT, the version number is auto-frobbed from tramp.el, +@c and the bug report address is auto-frobbed from configure.ac. @include trampver.texi @settitle @value{tramp} @value{trampver} User Manual @c %**end of header @@ -52,7 +51,7 @@ editing package for Emacs. @value{tramp} stands for ``Transparent Remote (file) Access, Multiple Protocol''. This package provides remote file editing, similar to -Ange FTP. +Ange FTP@. The difference is that Ange FTP uses FTP to transfer files between the local and the remote host, whereas @value{tramp} uses a combination of @@ -968,7 +967,7 @@ after a predefined timeout. @cindex @option{ftp} method When @value{tramp} uses @option{ftp}, it forwards requests to whatever -ftp program is specified by Ange FTP. This external program must be +ftp program is specified by Ange FTP@. This external program must be capable of servicing requests from @value{tramp}. @item @option{smb} @@ -1092,8 +1091,8 @@ numbers are not applicable to Android devices connected through USB@. The program @command{rclone} allows to access different system storages in the cloud, see @url{https://rclone.org/} for a list of supported systems. If the @command{rclone} program isn't found in -your @env{PATH} environment variable, you can tell Tramp its absolute -path via the user option @code{tramp-rclone-program}. +your @env{PATH} environment variable, you can tell @value{tramp} its +absolute path via the user option @code{tramp-rclone-program}. A system storage must be configured via the @command{rclone config} command, outside Emacs. If you have configured a storage in @@ -1108,7 +1107,7 @@ User names are part of the @command{rclone} configuration, and not needed in the remote file name. If a user name is contained in the remote file name, it is ignored. -Internally, Tramp mounts the remote system storage at location +Internally, @value{tramp} mounts the remote system storage at location @file{/tmp/tramp.rclone.storage}, with @file{storage} being the name of the configured system storage. @@ -1538,8 +1537,8 @@ Host host.other.domain @end group @end example -@code{nc} is BSD's netcat program, which establishes HTTP tunnels. Any -other program with such a feature could be used as well. +@code{nc} is BSD's netcat program, which establishes HTTP tunnels. +Any other program with such a feature could be used as well. In the example, opening @file{@trampfn{ssh,host.your.domain,}} passes the HTTP proxy server @samp{proxy.your.domain} on port 3128. @@ -1615,7 +1614,7 @@ Integration for LXD containers. A container is accessed via @cindex method @option{git} @cindex @option{git} method Browing git repositories with @code{magit}. A versioned file is accessed via -@file{@trampfn{git,rev@@root-dir,/path/to/file}}. @samp{rev} is a git +@file{@trampfn{git,rev@@root-dir,/path/to/file}}. @samp{rev} is a git revision, and @samp{root-dir} is a virtual host name for the root directory, specified in @code{magit-tramp-hosts-alist}. @@ -2642,7 +2641,7 @@ names. Beside the @code{default} value, @var{syntax} can be @item @code{simplified} @cindex simplified syntax -The remote file name syntax is similar to the syntax used by Ange FTP. +The remote file name syntax is similar to the syntax used by Ange FTP@. A remote file name has the form @code{@value{prefix}user@@host@value{postfix}path/to/file}. The @code{user@@} part is optional, and the method is determined by @@ -4372,7 +4371,7 @@ handlers. @vindex non-essential Sometimes, it is not convenient to open a new connection to a remote host, including entering the password and alike. For example, this is -nasty for packages providing file name completion. Such a package +nasty for packages providing file name completion. Such a package could signal to @value{tramp}, that they don't want it to establish a new connection. Use the variable @code{non-essential} temporarily and bind it to non-@code{nil} value. diff --git a/etc/AUTHORS b/etc/AUTHORS index 73c5245678f..2f7e01575bd 100644 --- a/etc/AUTHORS +++ b/etc/AUTHORS @@ -163,7 +163,7 @@ Alexandru Harsanyi: wrote soap-client.el soap-inspect.el and changed emacs3.py vc-hooks.el vc.el xml.el Alex Branham: changed bibtex.el dired-x.el dired.el em-rebind.el eww.el - imenu.el modes.texi programs.texi + imenu.el indent.el modes.texi programs.texi text.texi Alex Coventry: changed files.el @@ -442,8 +442,8 @@ Bartosz Duszel: changed allout.el bib-mode.el cc-cmds.el hexl.el icon.el Basil L. Contovounesios: changed simple.el message.el sequences.texi bibtex.el css-mode-tests.el css-mode.el customize.texi display.texi - gnus-art.el json-tests.el json.el lists.texi man.el modes.texi rcirc.el - shr-color.el text.texi url-handlers.el + gnus-art.el json-tests.el json.el lists.texi man.el modes.texi + newcomment.el rcirc.el shr-color.el text.texi url-handlers.el Bastian Beischer: changed include.el mru-bookmark.el refs.el semantic/complete.el senator.el @@ -1354,8 +1354,8 @@ Eli Zaretskii: wrote [bidirectional display in xdisp.c] tty-colors.el and changed xdisp.c msdos.c w32.c display.texi w32fns.c simple.el files.el fileio.c keyboard.c w32proc.c files.texi w32term.c text.texi - dispnew.c frames.texi emacs.c dispextern.h lisp.h process.c term.c - window.c and 1125 other files + dispnew.c emacs.c frames.texi dispextern.h lisp.h window.c process.c + term.c and 1125 other files Emanuele Giaquinta: changed configure.ac rxvt.el charset.c etags.c fontset.c frame.el gnus-faq.texi loadup.el lread.c sh-script.el @@ -1380,7 +1380,7 @@ Eric Abrahamsen: changed eieio-base.el registry.el nnimap.el gnus-registry.el files.el files.texi windows.texi eieio-test-persist.el eieio.el gnus-start.el gnus-sum.el gnus.texi nnir.el buffers.texi checkdoc.el files-tests.el gnus-bcklg.el gnus-group.el nnmairix.el - org.el org.texi and 3 other files + org.el org.texi and 4 other files Eric Bélanger: changed image.c @@ -1682,9 +1682,9 @@ Geert Kloosterman: changed which-func.el Gemini Lasswell: wrote edebug-tests.el kmacro-tests.el testcover-tests.el and changed edebug.el cl-macs.el cl-generic.el ert-x.el cl-print.el edebug-test-code.el edebug.texi eieio-compat.el generator.el subr.el - autorevert-tests.el cl-print-tests.el emacs-lisp/debug.el eval-tests.el - eval.c filenotify-tests.el generator-tests.el kmacro.el lread.c - map-tests.el map.el and 9 other files + autorevert-tests.el cl-print-tests.el eieio.texi emacs-lisp/debug.el + eval-tests.el eval.c filenotify-tests.el generator-tests.el kmacro.el + lread.c map-tests.el and 10 other files Geoff Gole: changed align.el ibuffer.el whitespace.el @@ -3258,6 +3258,8 @@ Matt Hodges: changed textmodes/table.el faces.el iswitchb.el simple.el edebug.texi eldoc.el em-hist.el em-pred.el fixit.texi icon.el ido.el locate.el paragraphs.el pcomplete.el repeat.el and 3 other files +Mattias Engdegård: changed subr.el + Matt Lundin: changed org-agenda.el org.el org-bibtex.el org-footnote.el ox-publish.el org-bbdb.el org-datetree.el org-gnus.el @@ -3270,7 +3272,7 @@ Matt Simmons: changed message.el Matt Swift: changed dired.el editfns.c lisp-mode.el mm-decode.el outline.el progmodes/compile.el rx.el simple.el startup.el -Mauro Aranda: changed files.texi os.texi +Mauro Aranda: changed autorevert.el files.texi os.texi Maxime Edouard Robert Froumentin: changed gnus-art.el mml.el @@ -3649,7 +3651,7 @@ Noam Postavsky: changed lisp-mode.el progmodes/python.el xdisp.c cl-macs.el lisp-mode-tests.el emacs-lisp/debug.el data.c simple.el term.el ert.el subr.el help-fns.el bytecomp.el cl-print.el elisp-mode.el eval.c ffap.el modes.texi search.c sh-script.el - cl-preloaded.el and 248 other files + cl-preloaded.el and 249 other files Nobuyoshi Nakada: co-wrote ruby-mode.el diff --git a/etc/HISTORY b/etc/HISTORY index b239904253b..bf03692d3ff 100644 --- a/etc/HISTORY +++ b/etc/HISTORY @@ -216,6 +216,8 @@ GNU Emacs 25.3 (2017-09-11) emacs-25.3 GNU Emacs 26.1 (2018-05-28) emacs-26.1 +GNU Emacs 26.2 (2019-04-12) emacs-26.2 + ---------------------------------------------------------------------- This file is part of GNU Emacs. diff --git a/etc/NEWS b/etc/NEWS index f41db027b28..82d27d7e744 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -846,6 +846,9 @@ directories in the destination. ** Help +--- +*** Description of variables and functions give an estimated first release + --- *** Output format of 'C-h l' ('view-lossage') has changed. For convenience, 'view-lossage' now displays the last keystrokes @@ -1061,6 +1064,12 @@ followed when Emacs writes the relevant history variables to the disk. *** The variable 'shell-file-name' can be set now as connection-local variable for remote shells. It still defaults to "/bin/sh". +** Single shell commands + +--- +*** 'shell-command-width' defines the number of display columns +available for output of asynchronous shell commands. + ** Pcomplete *** The function 'pcomplete-uniquify-list' has been renamed from @@ -1497,6 +1506,9 @@ performs (setq-local indent-line-function #'indent-relative). * Lisp Changes in Emacs 27.1 +** New 'help-fns-describe-variable-functions' hook. +Makes it possible to add metadata information to describe-variable. + ** i18n (internationalization) *** ngettext can be used now to return the right plural form diff --git a/etc/NEWS.1-17 b/etc/NEWS.1-17 index 758ef65ed95..1ce36fe99da 100644 --- a/etc/NEWS.1-17 +++ b/etc/NEWS.1-17 @@ -2339,9 +2339,9 @@ It's Beat CCA Week. ** Lisp macros now exist. For example, you can write - (defmacro cadr (arg) (list 'car (list 'cdr arg))) + (defmacro mycadr (arg) (list 'car (list 'cdr arg))) and then the expression - (cadr foo) + (mycadr foo) will expand into (car (cdr foo)) diff --git a/lib/_Noreturn.h b/lib/_Noreturn.h index 7594e4b0c0b..db9b45554c5 100644 --- a/lib/_Noreturn.h +++ b/lib/_Noreturn.h @@ -1,3 +1,19 @@ +/* A C macro for declaring that a function does not return. + Copyright (C) 2011-2019 Free Software Foundation, Inc. + + This program 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. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + #ifndef _Noreturn # if (defined __cplusplus \ && ((201103 <= __cplusplus && !(__GNUC__ == 4 && __GNUC_MINOR__ == 7)) \ diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index 0d9a885be3d..1450df9f638 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -179,6 +179,7 @@ CAIRO_LIBS = @CAIRO_LIBS@ CC = @CC@ CFLAGS = @CFLAGS@ CFLAGS_SOUND = @CFLAGS_SOUND@ +CHECK_STRUCTS = @CHECK_STRUCTS@ CLIENTRES = @CLIENTRES@ CLIENTW = @CLIENTW@ CM_OBJ = @CM_OBJ@ diff --git a/lisp/align.el b/lisp/align.el index fd88d0eda42..443237b451b 100644 --- a/lisp/align.el +++ b/lisp/align.el @@ -411,7 +411,7 @@ The possible settings for `align-region-separate' are: (c-variable-declaration (regexp . ,(concat "[*&0-9A-Za-z_]>?[&*]*\\(\\s-+[*&]*\\)" "[A-Za-z_][0-9A-Za-z:_]*\\s-*\\(\\()\\|" - "=[^=\n].*\\|(.*)\\|\\(\\[.*\\]\\)*\\)?" + "=[^=\n].*\\|(.*)\\|\\(\\[.*\\]\\)*\\)" "\\s-*[;,]\\|)\\s-*$\\)")) (group . 1) (modes . align-c++-modes) diff --git a/lisp/cedet/srecode/srt-mode.el b/lisp/cedet/srecode/srt-mode.el index 2ad7ffcdb87..6bf2d51ab41 100644 --- a/lisp/cedet/srecode/srt-mode.el +++ b/lisp/cedet/srecode/srt-mode.el @@ -64,7 +64,7 @@ (defvar srecode-font-lock-keywords '( ;; Template - ("^\\(template\\)\\s-+\\(\\w*\\)\\(\\( \\(:\\w+\\)\\|\\)+\\)$" + ("^\\(template\\)\\s-+\\(\\w*\\)\\(\\( \\(:\\w+\\)\\)*\\)$" (1 font-lock-keyword-face) (2 font-lock-function-name-face) (3 font-lock-builtin-face )) diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 33d49647638..44cca6136c0 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -879,7 +879,8 @@ (put 'symbolp 'byte-optimizer 'byte-optimize-predicate) (put 'stringp 'byte-optimizer 'byte-optimize-predicate) (put 'string< 'byte-optimizer 'byte-optimize-predicate) -(put 'string-lessp 'byte-optimizer 'byte-optimize-predicate) +(put 'string-lessp 'byte-optimizer 'byte-optimize-predicate) +(put 'proper-list-p 'byte-optimizer 'byte-optimize-predicate) (put 'logand 'byte-optimizer 'byte-optimize-predicate) (put 'logior 'byte-optimizer 'byte-optimize-predicate) diff --git a/lisp/emacs-lisp/copyright.el b/lisp/emacs-lisp/copyright.el index 2726bbc1f3f..be335838e33 100644 --- a/lisp/emacs-lisp/copyright.el +++ b/lisp/emacs-lisp/copyright.el @@ -52,7 +52,7 @@ This is useful for ChangeLogs." (defcustom copyright-regexp "\\(©\\|@copyright{}\\|[Cc]opyright\\s *:?\\s *\\(?:(C)\\)?\ \\|[Cc]opyright\\s *:?\\s *©\\)\ -\\s *\\(?:[^0-9\n]*\\s *\\)?\ +\\s *[^0-9\n]*\\s *\ \\([1-9]\\([-0-9, ';/*%#\n\t]\\|\\s<\\|\\s>\\)*[0-9]+\\)" "What your copyright notice looks like. The second \\( \\) construct must match the years." diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index 2854cde19cc..210830a2b49 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -1285,7 +1285,7 @@ add things to `%s' instead." (pcase-let ((`(,nick ,login ,host) (erc-parse-user (erc-response.sender parsed)))) ;; strip the stupid combined JOIN facility (IRC 2.9) - (if (string-match "^\\(.*\\)?\^g.*$" chnl) + (if (string-match "^\\(.*\\)\^g.*$" chnl) (setq chnl (match-string 1 chnl))) (save-excursion (let* ((str (cond diff --git a/lisp/erc/erc-desktop-notifications.el b/lisp/erc/erc-desktop-notifications.el index 56b93925ced..41b7420320c 100644 --- a/lisp/erc/erc-desktop-notifications.el +++ b/lisp/erc/erc-desktop-notifications.el @@ -1,4 +1,4 @@ -;; erc-desktop-notifications.el -- Send notification on PRIVMSG or mentions +;; erc-desktop-notifications.el -- Send notification on PRIVMSG or mentions -*- lexical-binding:t -*- ;; Copyright (C) 2012-2019 Free Software Foundation, Inc. @@ -59,13 +59,19 @@ This will replace the last notification sent with this function." (dbus-ignore-errors (setq erc-notifications-last-notification - (notifications-notify :bus erc-notifications-bus - :title (xml-escape-string nick) - :body (xml-escape-string msg) - :replaces-id erc-notifications-last-notification - :app-icon erc-notifications-icon)))) + (let ((channel (current-buffer))) + (notifications-notify :bus erc-notifications-bus + :title (format "%s in %s" + (xml-escape-string nick) + channel) + :body (xml-escape-string msg) + :replaces-id erc-notifications-last-notification + :app-icon erc-notifications-icon + :actions '("default" "Switch to buffer") + :on-action (lambda (&rest _) + (pop-to-buffer channel))))))) -(defun erc-notifications-PRIVMSG (proc parsed) +(defun erc-notifications-PRIVMSG (_proc parsed) (let ((nick (car (erc-parse-user (erc-response.sender parsed)))) (target (car (erc-response.command-args parsed))) (msg (erc-response.contents parsed))) diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el index 117b6783b8d..884c594b9ed 100644 --- a/lisp/erc/erc-goodies.el +++ b/lisp/erc/erc-goodies.el @@ -548,7 +548,7 @@ channel that has weird people talking in morse to each other. See also `unmorse-region'." (goto-char (point-min)) - (when (re-search-forward "[.-]+\\([.-]*/? *\\)+[.-]+/?" nil t) + (when (re-search-forward "[.-]+[./ -]*[.-]/?" nil t) (save-restriction (narrow-to-region (match-beginning 0) (match-end 0)) ;; Turn " / " into " " diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el index 144496bdd2a..b1e4091c975 100644 --- a/lisp/gnus/gnus-group.el +++ b/lisp/gnus/gnus-group.el @@ -1320,7 +1320,7 @@ if it is a string, only list groups matching REGEXP." gnus-group-listed-groups) ;; List living groups, according to order in `gnus-group-list'. (dolist (g (cdr gnus-group-list)) - (setq info (nth 1 (gethash g gnus-newsrc-hashtb)) + (setq info (gnus-get-info g) group (gnus-info-group info) params (gnus-info-params info) unread (gnus-group-unread group)) @@ -1389,39 +1389,35 @@ if it is a string, only list groups matching REGEXP." ;; List zombies and killed lists somewhat faster, which was ;; suggested by Jack Vinson . It does ;; this by ignoring the group format specification altogether. - (let (group) - (if (> (length groups) gnus-group-listing-limit) - (while groups - (setq group (pop groups)) - (when (gnus-group-prepare-logic - group - (or (not regexp) - (and (stringp regexp) (string-match regexp group)) - (and (functionp regexp) (funcall regexp group)))) - (add-text-properties - (point) (prog1 (1+ (point)) - (insert " " mark " *: " - (gnus-group-decoded-name group) - "\n")) - (list 'gnus-group (gethash group gnus-active-hashtb) - 'gnus-unread t - 'gnus-level level)))) - (while groups - (setq group (pop groups)) + (if (nthcdr gnus-group-listing-limit groups) + (dolist (group groups) (when (gnus-group-prepare-logic group - (or (not regexp) - (and (stringp regexp) (string-match regexp group)) - (and (functionp regexp) (funcall regexp group)))) - (gnus-group-insert-group-line - group level nil - (let ((active (gnus-active group))) - (if active - (if (zerop (cdr active)) - 0 - (- (1+ (cdr active)) (car active))) - nil)) - (gnus-method-simplify (gnus-find-method-for-group group)))))))) + (cond ((not regexp)) + ((stringp regexp) (string-match-p regexp group)) + ((functionp regexp) (funcall regexp group)))) + (add-text-properties + (point) (prog1 (1+ (point)) + (insert " " mark " *: " + (gnus-group-decoded-name group) + "\n")) + (list 'gnus-group group + 'gnus-unread t + 'gnus-level level)))) + (dolist (group groups) + (when (gnus-group-prepare-logic + group + (cond ((not regexp)) + ((stringp regexp) (string-match-p regexp group)) + ((functionp regexp) (funcall regexp group)))) + (gnus-group-insert-group-line + group level nil + (let ((active (gnus-active group))) + (and active + (if (zerop (cdr active)) + 0 + (- (cdr active) (car active) -1)))) + (gnus-method-simplify (gnus-find-method-for-group group))))))) (defun gnus-group-update-group-line () "Update the current line in the group buffer." @@ -1527,7 +1523,7 @@ if it is a string, only list groups matching REGEXP." (int-to-string (max 0 (- gnus-tmp-number-total number))) "*")) (gnus-tmp-subscribed - (cond ((<= gnus-tmp-level gnus-level-subscribed) ? ) + (cond ((<= gnus-tmp-level gnus-level-subscribed) ?\s) ((<= gnus-tmp-level gnus-level-unsubscribed) ?U) ((= gnus-tmp-level gnus-level-zombie) ?Z) (t ?K))) @@ -1546,7 +1542,7 @@ if it is a string, only list groups matching REGEXP." (gnus-tmp-moderated (if (and gnus-moderated-hashtb (gethash gnus-tmp-group gnus-moderated-hashtb)) - ?m ? )) + ?m ?\s)) (gnus-tmp-moderated-string (if (eq gnus-tmp-moderated ?m) "(m)" "")) (gnus-tmp-group-icon (gnus-group-get-icon gnus-tmp-group)) @@ -1560,15 +1556,15 @@ if it is a string, only list groups matching REGEXP." (if (and (numberp number) (zerop number) (cdr (assq 'tick gnus-tmp-marked))) - ?* ? )) + ?* ?\s)) (gnus-tmp-summary-live (if (and (not gnus-group-is-exiting-p) (gnus-buffer-live-p (gnus-summary-buffer-name gnus-tmp-group))) - ?* ? )) + ?* ?\s)) (gnus-tmp-process-marked (if (member gnus-tmp-group gnus-group-marked) - gnus-process-mark ? )) + gnus-process-mark ?\s)) (buffer-read-only nil) beg end gnus-tmp-header) ; passed as parameter to user-funcs. @@ -1768,10 +1764,8 @@ already. If INFO-UNCHANGED is non-nil, dribble buffer is not updated." (defun gnus-group-group-name () "Get the name of the newsgroup on the current line." (let ((group (get-text-property (point-at-bol) 'gnus-group))) - (when group - (if (stringp group) - group - (symbol-name group))))) + (cond ((stringp group) group) + (group (symbol-name group))))) (defun gnus-group-group-level () "Get the level of the newsgroup on the current line." @@ -1791,7 +1785,7 @@ already. If INFO-UNCHANGED is non-nil, dribble buffer is not updated." (defun gnus-group-new-mail (group) (if (nnmail-new-mail-p (gnus-group-real-name group)) gnus-new-mail-mark - ? )) + ?\s)) (defun gnus-group-level (group) "Return the estimated level of GROUP." @@ -1881,7 +1875,7 @@ If FIRST-TOO, the current line is also eligible as a target." (if unmark (progn (setq gnus-group-marked (delete group gnus-group-marked)) - (insert-char ? 1 t)) + (insert-char ?\s 1 t)) (setq gnus-group-marked (cons group (delete group gnus-group-marked))) (insert-char gnus-process-mark 1 t))) @@ -2561,10 +2555,10 @@ If TEST-MARKED, the line must be marked." (when group (let ((start (point)) (active (and (or - ;; some kind of group may be only there. - (gethash group gnus-active-hashtb) - ;; all groups (but with exception) are there. - (gethash group gnus-newsrc-hashtb)) + ;; Some kind of group may be only there. + (gnus-active group) + ;; All groups (but with exception) are there. + (gnus-group-entry group)) group))) (beginning-of-line) (cond @@ -4013,15 +4007,9 @@ entail asking the server for the groups." (gnus-agent gnus-plugged)); If we're actually plugged, store the active file in the agent. (gnus-read-active-file))) ;; Find all groups and sort them. - (let ((groups - (sort - (hash-table-keys gnus-active-hashtb) - 'string<)) - (buffer-read-only nil) - group) + (let ((buffer-read-only nil)) (erase-buffer) - (while groups - (setq group (pop groups)) + (dolist (group (sort (hash-table-keys gnus-active-hashtb) #'string<)) (add-text-properties (point) (prog1 (1+ (point)) (insert " *: " @@ -4149,20 +4137,19 @@ If DONT-SCAN is non-nil, scan non-activated groups as well." (when (not (or gnus-description-hashtb (gnus-read-all-descriptions-files))) (error "Couldn't request descriptions file")) - (let ((buffer-read-only nil) - (groups (sort (hash-table-keys gnus-description-hashtb))) - b) + (let ((buffer-read-only nil)) (erase-buffer) - (dolist (group groups) - (setq b (point)) - (let ((charset (gnus-group-name-charset nil group))) + (dolist (group (sort (hash-table-keys gnus-description-hashtb) #'string<)) + (let ((b (point)) + (desc (gethash group gnus-description-hashtb)) + (charset (gnus-group-name-charset nil group))) (insert (format " *: %-20s %s\n" (gnus-group-name-decode group charset) - (gnus-group-name-decode group charset)))) - (add-text-properties - b (1+ b) (list 'gnus-group (intern group gnus-description-hashtb) - 'gnus-unread t 'gnus-marked nil - 'gnus-level (1+ gnus-level-subscribed)))) + (gnus-group-name-decode desc charset))) + (add-text-properties + b (1+ b) (list 'gnus-group group + 'gnus-unread t 'gnus-marked nil + 'gnus-level (1+ gnus-level-subscribed))))) (goto-char (point-min)) (gnus-group-position-point))) diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 06b4ec8c209..50d69e70de4 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -40,7 +40,21 @@ "List of functions to run in help buffer in `describe-function'. Those functions will be run after the header line and argument list was inserted, and before the documentation will be inserted. -The functions will receive the function name as argument.") +The functions will receive the function name as argument. +They can assume that a newline was output just before they were called, +and they should terminate any of their own output with a newline. +By convention they should indent their output by 2 spaces.") + +(defvar help-fns-describe-variable-functions nil + "List of functions to run in help buffer in `describe-variable'. +Those functions will be run after the header line and value was inserted, +and before the documentation will be inserted. +The functions will receive the variable name as argument. +They can assume that a newline was output just before they were called, +and they should terminate any of their own output with a newline. +By convention they should indent their output by 2 spaces. +Current buffer is the buffer in which we queried the variable, +and the output should go to `standard-output'.") ;; Functions @@ -412,7 +426,7 @@ suitable file is found, return nil." (defun help-fns--compiler-macro (function) (let ((handler (function-get function 'compiler-macro))) (when handler - (insert "\nThis function has a compiler macro") + (insert " This function has a compiler macro") (if (symbolp handler) (progn (insert (format-message " `%s'" handler)) @@ -486,7 +500,7 @@ suitable file is found, return nil." (get function 'derived-mode-parent)))) (when parent-mode - (insert (substitute-command-keys "\nParent mode: `")) + (insert (substitute-command-keys " Parent mode: `")) (let ((beg (point))) (insert (format "%s" parent-mode)) (make-text-button beg (point) @@ -500,15 +514,15 @@ suitable file is found, return nil." (get function 'byte-obsolete-info))) (use (car obsolete))) (when obsolete - (insert "\nThis " + (insert " This " (if (eq (car-safe (symbol-function function)) 'macro) "macro" "function") " is obsolete") (when (nth 2 obsolete) (insert (format " since %s" (nth 2 obsolete)))) - (insert (cond ((stringp use) (concat ";\n" use)) - (use (format-message ";\nuse `%s' instead." use)) + (insert (cond ((stringp use) (concat ";\n " use)) + (use (format-message ";\n use `%s' instead." use)) (t ".")) "\n")))) @@ -538,17 +552,65 @@ FILE is the file where FUNCTION was probably defined." (memq function byte-compile-interactive-only-functions))))) (when interactive-only - (insert "\nThis function is for interactive use only" + (insert " This function is for interactive use only" ;; Cf byte-compile-form. (cond ((stringp interactive-only) - (format ";\nin Lisp code %s" interactive-only)) + (format ";\n in Lisp code %s" interactive-only)) ((and (symbolp 'interactive-only) (not (eq interactive-only t))) - (format-message ";\nin Lisp code use `%s' instead." + (format-message ";\n in Lisp code use `%s' instead." interactive-only)) (t ".")) "\n"))))) +(add-hook 'help-fns-describe-function-functions #'help-fns--side-effects) +(defun help-fns--side-effects (function) + (when (and (symbolp function) + (or (function-get function 'pure) + (function-get function 'side-effect-free))) + (insert " This function does not change global state, " + "including the match data.\n"))) + +(defun help-fns--first-release (symbol) + "Return the likely first release that defined SYMBOL." + ;; Code below relies on the etc/NEWS* files. + ;; FIXME: Maybe we should also use the */ChangeLog* files when available. + ;; FIXME: Maybe we should also look for announcements of the addition + ;; of the *packages* in which the function is defined. + (let* ((name (symbol-name symbol)) + (re (concat "\\_<" (regexp-quote name) "\\_>")) + (news (directory-files data-directory t "\\`NEWS.[1-9]")) + (first nil)) + (with-temp-buffer + (dolist (f news) + (erase-buffer) + (insert-file-contents f) + (goto-char (point-min)) + (search-forward "\n*") + (while (re-search-forward re nil t) + (save-excursion + ;; Almost all entries are of the form "* ... in Emacs NN.MM." + ;; but there are also a few in the form "* Emacs NN.MM is a bug + ;; fix release ...". + (if (not (re-search-backward "^\\*.* Emacs \\([0-9.]+[0-9]\\)" + nil t)) + (message "Ref found in non-versioned section in %S" + (file-name-nondirectory f)) + (let ((version (match-string 1))) + (when (or (null first) (version< version first)) + (setq first version)))))))) + first)) + +(add-hook 'help-fns-describe-function-functions + #'help-fns--mention-first-release) +(add-hook 'help-fns-describe-variable-functions + #'help-fns--mention-first-release) +(defun help-fns--mention-first-release (object) + (let ((first (if (symbolp object) (help-fns--first-release object)))) + (when first + (princ (format " Probably introduced at or before Emacs version %s.\n" + first))))) + (defun help-fns-short-filename (filename) (let* ((abbrev (abbreviate-file-name filename)) (short abbrev)) @@ -611,9 +673,9 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)." (memq (car-safe def) '(macro lambda closure))) (stringp file-name) (help-fns--autoloaded-p function file-name)) - (if (commandp def) - "an interactive autoloaded " - "an autoloaded ") + (concat + "an autoloaded " (if (commandp def) + "interactive ")) (if (commandp def) "an interactive " "a ")))) ;; Print what kind of function-like object FUNCTION is. @@ -627,14 +689,16 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)." (aliased (format-message "an alias for `%s'" real-def)) ((subrp def) - (if (eq 'unevalled (cdr (subr-arity def))) - (concat beg "special form") - (concat beg "built-in function"))) + (concat beg (if (eq 'unevalled (cdr (subr-arity def))) + "special form" + "built-in function"))) ((autoloadp def) - (format "%s autoloaded %s" - (if (commandp def) "an interactive" "an") - (if (eq (nth 4 def) 'keymap) "keymap" - (if (nth 4 def) "Lisp macro" "Lisp function")))) + (format "an autoloaded %s" + (cond + ((commandp def) "interactive Lisp function") + ((eq (nth 4 def) 'keymap) "keymap") + ((nth 4 def) "Lisp macro") + (t "Lisp function")))) ((or (eq (car-safe def) 'macro) ;; For advised macros, def is a lambda ;; expression or a byte-code-function-p, so we @@ -685,6 +749,10 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)." (help-xref-button 1 'help-function-def function file-name)))) (princ ".")))) +(defun help-fns--ensure-empty-line () + (unless (eolp) (insert "\n")) + (unless (eq ?\n (char-before (1- (point)))) (insert "\n"))) + ;;;###autoload (defun describe-function-1 (function) (let ((pt1 (with-current-buffer (help-buffer) (point)))) @@ -722,12 +790,10 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)." real-function key-bindings-buffer) ;; E.g. an alias for a not yet defined function. ((invalid-function void-function) doc-raw)))) + (help-fns--ensure-empty-line) (run-hook-with-args 'help-fns-describe-function-functions function) - (insert "\n" (or doc "Not documented."))) - (when (or (function-get function 'pure) - (function-get function 'side-effect-free)) - (insert "\nThis function does not change global state, " - "including the match data.")) + (help-fns--ensure-empty-line) + (insert (or doc "Not documented."))) ;; Avoid asking the user annoying questions if she decides ;; to save the help buffer, when her locale's codeset ;; isn't UTF-8. @@ -830,7 +896,6 @@ it is displayed along with the global value." (message "You did not specify a variable") (save-excursion (let ((valvoid (not (with-current-buffer buffer (boundp variable)))) - (permanent-local (get variable 'permanent-local)) val val-start-pos locus) ;; Extract the value before setting up the output buffer, ;; in case `buffer' *is* the output buffer. @@ -846,26 +911,26 @@ it is displayed along with the global value." (prin1 variable) (setq file-name (find-lisp-object-file-name variable 'defvar)) - (if file-name - (progn - (princ (format-message - " is a variable defined in `%s'.\n" - (if (eq file-name 'C-source) - "C source code" - (file-name-nondirectory file-name)))) - (with-current-buffer standard-output - (save-excursion - (re-search-backward (substitute-command-keys - "`\\([^`']+\\)'") - nil t) - (help-xref-button 1 'help-variable-def - variable file-name))) - (if valvoid - (princ "It is void as a variable.") - (princ "Its "))) - (if valvoid - (princ " is void as a variable.") - (princ (substitute-command-keys "'s "))))) + (princ (if file-name + (progn + (princ (format-message + " is a variable defined in `%s'.\n" + (if (eq file-name 'C-source) + "C source code" + (file-name-nondirectory file-name)))) + (with-current-buffer standard-output + (save-excursion + (re-search-backward (substitute-command-keys + "`\\([^`']+\\)'") + nil t) + (help-xref-button 1 'help-variable-def + variable file-name))) + (if valvoid + "It is void as a variable." + "Its ")) + (if valvoid + " is void as a variable." + (substitute-command-keys "'s "))))) (unless valvoid (with-current-buffer standard-output (setq val-start-pos (point)) @@ -894,7 +959,7 @@ it is displayed along with the global value." (let* ((sv (get variable 'standard-value)) (origval (and (consp sv) (condition-case nil - (eval (car sv)) + (eval (car sv) t) (error :help-eval-error)))) from) (when (and (consp sv) @@ -969,132 +1034,17 @@ it is displayed along with the global value." (let* ((alias (condition-case nil (indirect-variable variable) (error variable))) - (obsolete (get variable 'byte-obsolete-variable)) - (watchpoints (get-variable-watchers variable)) - (use (car obsolete)) - (safe-var (get variable 'safe-local-variable)) (doc (or (documentation-property variable 'variable-documentation) (documentation-property - alias 'variable-documentation))) - (extra-line nil)) + alias 'variable-documentation)))) - ;; Mention if it's a local variable. - (cond - ((and (local-variable-if-set-p variable) - (or (not (local-variable-p variable)) - (with-temp-buffer - (local-variable-if-set-p variable)))) - (setq extra-line t) - (princ " Automatically becomes ") - (if permanent-local - (princ "permanently ")) - (princ "buffer-local when set.\n")) - ((not permanent-local)) - ((bufferp locus) - (setq extra-line t) - (princ - (substitute-command-keys - " This variable's buffer-local value is permanent.\n"))) - (t - (setq extra-line t) - (princ (substitute-command-keys - " This variable's value is permanent \ -if it is given a local binding.\n")))) + (with-current-buffer buffer + (run-hook-with-args 'help-fns-describe-variable-functions + variable)) - ;; Mention if it's an alias. - (unless (eq alias variable) - (setq extra-line t) - (princ (format-message - " This variable is an alias for `%s'.\n" - alias))) - - (when obsolete - (setq extra-line t) - (princ " This variable is obsolete") - (if (nth 2 obsolete) - (princ (format " since %s" (nth 2 obsolete)))) - (princ (cond ((stringp use) (concat ";\n " use)) - (use (format-message ";\n use `%s' instead." - (car obsolete))) - (t "."))) - (terpri)) - - (when watchpoints - (setq extra-line t) - (princ " Calls these functions when changed: ") - (princ watchpoints) - (terpri)) - - (when (member (cons variable val) - (with-current-buffer buffer - file-local-variables-alist)) - (setq extra-line t) - (if (member (cons variable val) - (with-current-buffer buffer - dir-local-variables-alist)) - (let ((file (and (buffer-file-name buffer) - (not (file-remote-p - (buffer-file-name buffer))) - (dir-locals-find-file - (buffer-file-name buffer)))) - (is-directory nil)) - (princ (substitute-command-keys - " This variable's value is directory-local")) - (when (consp file) ; result from cache - ;; If the cache element has an mtime, we - ;; assume it came from a file. - (if (nth 2 file) - ;; (car file) is a directory. - (setq file (dir-locals--all-files (car file))) - ;; Otherwise, assume it was set directly. - (setq file (car file) - is-directory t))) - (if (null file) - (princ ".\n") - (princ ", set ") - (princ (substitute-command-keys - (cond - (is-directory "for the directory\n `") - ;; Many files matched. - ((and (consp file) (cdr file)) - (setq file (file-name-directory (car file))) - (format "by one of the\n %s files in the directory\n `" - dir-locals-file)) - (t (setq file (car file)) - "by the file\n `")))) - (with-current-buffer standard-output - (insert-text-button - file 'type 'help-dir-local-var-def - 'help-args (list variable file))) - (princ (substitute-command-keys "'.\n")))) - (princ (substitute-command-keys - " This variable's value is file-local.\n")))) - - (when (memq variable ignored-local-variables) - (setq extra-line t) - (princ " This variable is ignored as a file-local \ -variable.\n")) - - ;; Can be both risky and safe, eg auto-fill-function. - (when (risky-local-variable-p variable) - (setq extra-line t) - (princ " This variable may be risky if used as a \ -file-local variable.\n") - (when (assq variable safe-local-variable-values) - (princ (substitute-command-keys - " However, you have added it to \ -`safe-local-variable-values'.\n")))) - - (when safe-var - (setq extra-line t) - (princ " This variable is safe as a file local variable ") - (princ "if its value\n satisfies the predicate ") - (princ (if (byte-code-function-p safe-var) - "which is a byte-compiled expression.\n" - (format-message "`%s'.\n" safe-var)))) - - (if extra-line (terpri)) + (with-current-buffer standard-output + (help-fns--ensure-empty-line)) (princ "Documentation:\n") (with-current-buffer standard-output (insert (or doc "Not documented as a variable.")))) @@ -1121,6 +1071,134 @@ file-local variable.\n") ;; Return the text we displayed. (buffer-string)))))))) +(add-hook 'help-fns-describe-variable-functions #'help-fns--var-safe-local) +(defun help-fns--var-safe-local (variable) + (let ((safe-var (get variable 'safe-local-variable))) + (when safe-var + (princ " This variable is safe as a file local variable ") + (princ "if its value\n satisfies the predicate ") + (princ (if (byte-code-function-p safe-var) + "which is a byte-compiled expression.\n" + (format-message "`%s'.\n" safe-var)))))) + +(add-hook 'help-fns-describe-variable-functions #'help-fns--var-risky) +(defun help-fns--var-risky (variable) + ;; Can be both risky and safe, eg auto-fill-function. + (when (risky-local-variable-p variable) + (princ " This variable may be risky if used as a \ +file-local variable.\n") + (when (assq variable safe-local-variable-values) + (princ (substitute-command-keys + " However, you have added it to \ +`safe-local-variable-values'.\n"))))) + +(add-hook 'help-fns-describe-variable-functions #'help-fns--var-ignored-local) +(defun help-fns--var-ignored-local (variable) + (when (memq variable ignored-local-variables) + (princ " This variable is ignored as a file-local \ +variable.\n"))) + +(add-hook 'help-fns-describe-variable-functions #'help-fns--var-file-local) +(defun help-fns--var-file-local (variable) + (when (boundp variable) + (let ((val (symbol-value variable))) + (when (member (cons variable val) + file-local-variables-alist) + (if (member (cons variable val) + dir-local-variables-alist) + (let ((file (and buffer-file-name + (not (file-remote-p buffer-file-name)) + (dir-locals-find-file buffer-file-name))) + (is-directory nil)) + (princ (substitute-command-keys + " This variable's value is directory-local")) + (when (consp file) ; result from cache + ;; If the cache element has an mtime, we + ;; assume it came from a file. + (if (nth 2 file) + ;; (car file) is a directory. + (setq file (dir-locals--all-files (car file))) + ;; Otherwise, assume it was set directly. + (setq file (car file) + is-directory t))) + (if (null file) + (princ ".\n") + (princ ", set ") + (princ (substitute-command-keys + (cond + (is-directory "for the directory\n `") + ;; Many files matched. + ((and (consp file) (cdr file)) + (setq file (file-name-directory (car file))) + (format "by one of the\n %s files in the directory\n `" + dir-locals-file)) + (t (setq file (car file)) + "by the file\n `")))) + (with-current-buffer standard-output + (insert-text-button + file 'type 'help-dir-local-var-def + 'help-args (list variable file))) + (princ (substitute-command-keys "'.\n")))) + (princ (substitute-command-keys + " This variable's value is file-local.\n"))))))) + +(add-hook 'help-fns-describe-variable-functions #'help-fns--var-watchpoints) +(defun help-fns--var-watchpoints (variable) + (let ((watchpoints (get-variable-watchers variable))) + (when watchpoints + (princ " Calls these functions when changed: ") + ;; FIXME: Turn function names into hyperlinks. + (princ watchpoints) + (terpri)))) + +(add-hook 'help-fns-describe-variable-functions #'help-fns--var-obsolete) +(defun help-fns--var-obsolete (variable) + (let* ((obsolete (get variable 'byte-obsolete-variable)) + (use (car obsolete))) + (when obsolete + (princ " This variable is obsolete") + (if (nth 2 obsolete) + (princ (format " since %s" (nth 2 obsolete)))) + (princ (cond ((stringp use) (concat ";\n " use)) + (use (format-message ";\n use `%s' instead." + (car obsolete))) + (t "."))) + (terpri)))) + +(add-hook 'help-fns-describe-variable-functions #'help-fns--var-alias) +(defun help-fns--var-alias (variable) + ;; Mention if it's an alias. + (let ((alias (condition-case nil + (indirect-variable variable) + (error variable)))) + (unless (eq alias variable) + (princ (format-message + " This variable is an alias for `%s'.\n" + alias))))) + +(add-hook 'help-fns-describe-variable-functions #'help-fns--var-bufferlocal) +(defun help-fns--var-bufferlocal (variable) + (let ((permanent-local (get variable 'permanent-local)) + (locus (variable-binding-locus variable))) + ;; Mention if it's a local variable. + (cond + ((and (local-variable-if-set-p variable) + (or (not (local-variable-p variable)) + (with-temp-buffer + (local-variable-if-set-p variable)))) + (princ " Automatically becomes ") + (if permanent-local + (princ "permanently ")) + (princ "buffer-local when set.\n")) + ((not permanent-local)) + ((bufferp locus) + (princ + (substitute-command-keys + " This variable's buffer-local value is permanent.\n"))) + (t + (princ (substitute-command-keys + " This variable's value is permanent \ +if it is given a local binding.\n")))))) (defvar help-xref-stack-item) diff --git a/lisp/mail/mail-extr.el b/lisp/mail/mail-extr.el index cb57d8ea016..a0b96886507 100644 --- a/lisp/mail/mail-extr.el +++ b/lisp/mail/mail-extr.el @@ -383,7 +383,7 @@ by translating things like \"foo!bar!baz@host\" into \"baz@bar.UUCP\"." ;; Matches telephone extensions. (defconst mail-extr-telephone-extension-pattern (purecopy - "\\(\\([Ee]xt\\|\\|[Tt]ph\\|[Tt]el\\|[Xx]\\).?\\)? *\\+?[0-9][- 0-9]+")) + "\\(\\([Ee]xt\\|[Tt]ph\\|[Tt]el\\|[Xx]\\).?\\)? *\\+?[0-9][- 0-9]+")) ;; Matches ham radio call signs. ;; Help from: Mat Maessen N2NJZ , Mark Feit diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index db9acbfc631..f3aa55f16f5 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -53,7 +53,7 @@ It is used for TCP/IP devices." "When this method name is used, forward all calls to Android Debug Bridge.") (defcustom tramp-adb-prompt - "^\\(?:[[:digit:]]*|?\\)?\\(?:[[:alnum:]\e;[]*@?[[:alnum:]]*[^#\\$]*\\)?[#\\$][[:space:]]" + "^[[:digit:]]*|?\\(?:[[:alnum:]\e;[]*@?[[:alnum:]]*[^#\\$]*\\)?[#\\$][[:space:]]" "Regexp used as prompt in almquist shell." :type 'string :version "24.4" diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 7d903c5769c..d9751a9f973 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -2903,7 +2903,8 @@ the result will be a local, non-Tramp, file name." ;; otherwise we might be interrupted by ;; `verify-visited-file-modtime'. (let ((buffer-undo-list t) - (inhibit-read-only t)) + (inhibit-read-only t) + (mark (point-max))) (clear-visited-file-modtime) (narrow-to-region (point-max) (point-max)) ;; We call `tramp-maybe-open-connection', in @@ -2916,7 +2917,12 @@ the result will be a local, non-Tramp, file name." (let ((pid (tramp-send-command-and-read v "echo $$"))) (process-put p 'remote-pid pid) (tramp-set-connection-property p "remote-pid" pid)) - (delete-region (point-min) (point-max)) + ;; `tramp-maybe-open-connection' and + ;; `tramp-send-command-and-read' could have + ;; trashed the connection buffer. Remove this. + (widen) + (delete-region mark (point-max)) + (narrow-to-region (point-max) (point-max)) ;; Now do it. (if command ;; Send the command. diff --git a/lisp/org/org-table.el b/lisp/org/org-table.el index b6e864fc9c9..147527da1d3 100644 --- a/lisp/org/org-table.el +++ b/lisp/org/org-table.el @@ -484,8 +484,8 @@ Line numbers are counted from the beginning of the table. This variable is initialized with `org-table-analyze'.") (defconst org-table-range-regexp - "@\\([-+]?I*[-+]?[0-9]*\\)?\\(\\$[-+]?[0-9]+\\)?\\(\\.\\.@?\\([-+]?I*[-+]?[0-9]*\\)?\\(\\$[-+]?[0-9]+\\)?\\)?" - ;; 1 2 3 4 5 + "@\\([-+]?I*[-+]?[0-9]*\\)\\(\\$[-+]?[0-9]+\\)?\\(\\.\\.@?\\([-+]?I*[-+]?[0-9]*\\)\\(\\$[-+]?[0-9]+\\)?\\)?" + ;; 1 2 3 4 5 "Regular expression for matching ranges in formulas.") (defconst org-table-range-regexp2 diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 1a8c5164906..f0b44d2183d 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -10953,7 +10953,8 @@ comment at the start of cc-engine.el for more info." (eq (char-after) ?\()) (setq braceassignp 'c++-noassign in-paren 'in-paren)) - ((looking-at c-pre-id-bracelist-key)) + ((looking-at c-pre-id-bracelist-key) + (setq braceassignp nil)) ((looking-at c-return-key)) ((and (looking-at c-symbol-start) (not (looking-at c-keywords-regexp))) @@ -10995,6 +10996,8 @@ comment at the start of cc-engine.el for more info." (setq pos (point)) (cond + ((not braceassignp) + nil) ((and after-type-id-pos (goto-char after-type-id-pos) (setq res (c-back-over-member-initializers)) @@ -11069,14 +11072,20 @@ comment at the start of cc-engine.el for more info." )))) nil) (t t)))))) - (when (and (eq braceassignp 'dontknow) - (/= (c-backward-token-2 1 t lim) 0)) - (if (save-excursion - (and c-has-compound-literals - (eq (c-backward-token-2 1 nil lim) 0) - (eq (char-after) ?\())) - (setq braceassignp t) - (setq braceassignp nil)))) + (when (eq braceassignp 'dontknow) + (cond ((and + (not (eq (char-after) ?,)) + (save-excursion + (c-backward-syntactic-ws) + (eq (char-before) ?}))) + (setq braceassignp nil)) + ((/= (c-backward-token-2 1 t lim) 0) + (if (save-excursion + (and c-has-compound-literals + (eq (c-backward-token-2 1 nil lim) 0) + (eq (char-after) ?\())) + (setq braceassignp t) + (setq braceassignp nil)))))) (cond (braceassignp @@ -11108,9 +11117,14 @@ comment at the start of cc-engine.el for more info." (and (consp res) (eq (car res) after-type-id-pos)))))) (cons bufpos (or in-paren inexpr-brace-list))) - ((eq (char-after) ?\;) - ;; Brace lists can't contain a semicolon, so we're done. - ;; (setq containing-sexp nil) + ((or (eq (char-after) ?\;) + ;; Brace lists can't contain a semicolon, so we're done. + (save-excursion + (c-backward-syntactic-ws) + (eq (char-before) ?})) + ;; They also can't contain a bare }, which is probably the end + ;; of a function. + ) nil) ((and (setq macro-start (point)) (c-forward-to-cpp-define-body) @@ -12720,6 +12734,13 @@ comment at the start of cc-engine.el for more info." (if (eq (char-after) ?<) (zerop (c-forward-token-2 1 t indent-point)) t) + (progn + (while + (and + (< (point) indent-point) + (looking-at c-class-id-suffix-ws-ids-key) + (zerop (c-forward-token-2 1 nil indent-point)))) + t) (eq (char-after) ?:)))) (goto-char placeholder) (c-add-syntax 'inher-cont (c-point 'boi))) diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 2dff5cf83c8..50f8b8473be 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -2049,6 +2049,19 @@ effect in the declaration, but are syntactically like whitespace." (c-lang-defvar c-type-decl-suffix-ws-ids-key (c-lang-const c-type-decl-suffix-ws-ids-key)) +(c-lang-defconst c-class-id-suffix-ws-ids-kwds + "\"Identifiers\" that when immediately following the identifier +of a class declaration have semantic effect in the declaration, +but are syntactically like whitespace." + t nil + c++ '("final")) + +(c-lang-defconst c-class-id-suffix-ws-ids-key + ;; An adorned regexp matching `c-class-id-suffix-ws-ids-kwds'. + t (c-make-keywords-re t (c-lang-const c-class-id-suffix-ws-ids-kwds))) +(c-lang-defvar c-class-id-suffix-ws-ids-key + (c-lang-const c-class-id-suffix-ws-ids-key)) + (c-lang-defconst c-class-decl-kwds "Keywords introducing declarations where the following block (if any) contains another declaration level that should be considered a class. diff --git a/lisp/progmodes/idlwave.el b/lisp/progmodes/idlwave.el index bded09d5038..6f56ce052a0 100644 --- a/lisp/progmodes/idlwave.el +++ b/lisp/progmodes/idlwave.el @@ -6454,10 +6454,10 @@ ARROW: Location of the arrow" ((string-match "\\`[ \t]*\\(pro\\|function\\)\\>" match-string) nil) - ((string-match "OBJ_NEW([ \t]*['\"]\\([a-zA-Z0-9$_]*\\)?\\'" + ((string-match "OBJ_NEW([ \t]*['\"][a-zA-Z0-9$_]*\\'" match-string) (setq cw 'class)) - ((string-match "\\ n 0) (setcdr (nthcdr (- (1- m) n) list) nil)) list)))) +;; The function's definition was moved to fns.c, +;; but it's easier to set properties here. +(put 'proper-list-p 'pure t) +(put 'proper-list-p 'side-effect-free 'error-free) + (defun delete-dups (list) "Destructively remove `equal' duplicates from LIST. Store the result in LIST and return it. LIST must be a proper list. diff --git a/lisp/url/url-http.el b/lisp/url/url-http.el index cf1952066a5..662b6664b13 100644 --- a/lisp/url/url-http.el +++ b/lisp/url/url-http.el @@ -150,15 +150,6 @@ request.") ;; These routines will allow us to implement persistent HTTP ;; connections. (defsubst url-http-debug (&rest args) - (if (eq quit-flag t) - (let ((proc (get-buffer-process (current-buffer)))) - ;; The user hit C-g, honor it! Some things can get in an - ;; incredibly tight loop (chunked encoding) - (if proc - (progn - (set-process-sentinel proc nil) - (set-process-filter proc nil))) - (error "Transfer interrupted!"))) (apply 'url-debug 'http args)) (defun url-http-mark-connection-as-busy (host port proc) diff --git a/lisp/url/url-misc.el b/lisp/url/url-misc.el index 4969cba6688..aa44ea78a22 100644 --- a/lisp/url/url-misc.el +++ b/lisp/url/url-misc.el @@ -88,7 +88,7 @@ (encoding "8bit") (data nil)) (save-excursion - (if (not (string-match "\\([^,]*\\)?," desc)) + (if (not (string-match "\\([^,]*\\)," desc)) (error "Malformed data URL: %s" desc) (setq mediatype (match-string 1 desc) data (url-unhex-string (substring desc (match-end 0)))) diff --git a/lisp/url/url-util.el b/lisp/url/url-util.el index 72ff4f171cd..5b8350642ff 100644 --- a/lisp/url/url-util.el +++ b/lisp/url/url-util.el @@ -61,8 +61,6 @@ If a list, it is a list of the types of messages to be logged." ;;;###autoload (defun url-debug (tag &rest args) - (if (eq quit-flag t) - (error "Interrupted!")) (if (or (eq url-debug t) (numberp url-debug) (and (listp url-debug) (memq tag url-debug))) diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index 8940c7e09a6..1d5a2cf69ab 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -2411,10 +2411,11 @@ and the position in MAX." (diff-syntax-fontify-hunk beg end t) (diff-syntax-fontify-hunk beg end nil))) -(defvar diff-syntax-fontify-revisions (make-hash-table :test 'equal)) - (eval-when-compile (require 'subr-x)) ; for string-trim-right +(defvar-local diff--syntax-file-attributes nil) +(put 'diff--syntax-file-attributes 'permanent-local t) + (defun diff-syntax-fontify-hunk (beg end old) "Highlight source language syntax in diff hunk between BEG and END. When OLD is non-nil, highlight the hunk from the old source." @@ -2444,33 +2445,38 @@ When OLD is non-nil, highlight the hunk from the old source." (when file (if (not revision) ;; Get properties from the current working revision - (when (and (not old) (file-exists-p file) + (when (and (not old) (file-readable-p file) (file-regular-p file)) (let ((buf (get-file-buffer (expand-file-name file)))) ;; Try to reuse an existing buffer (if buf (with-current-buffer buf (diff-syntax-fontify-props nil text line-nb)) - ;; Get properties from the file - (with-temp-buffer - (insert-file-contents file) + ;; Get properties from the file. + (with-current-buffer (get-buffer-create + " *diff-syntax-file*") + (let ((attrs (file-attributes file))) + (if (equal diff--syntax-file-attributes attrs) + ;; Same file as last-time, unmodified. + ;; Reuse buffer as-is. + (setq file nil) + (insert-file-contents file) + (setq diff--syntax-file-attributes attrs))) (diff-syntax-fontify-props file text line-nb))))) ;; Get properties from a cached revision (let* ((buffer-name (format " *diff-syntax:%s.~%s~*" (expand-file-name file) revision)) - (buffer (gethash buffer-name - diff-syntax-fontify-revisions))) - (unless (and buffer (buffer-live-p buffer)) - (let* ((vc-buffer (ignore-errors - (vc-find-revision-no-save - (expand-file-name file) revision - diff-vc-backend - (get-buffer-create buffer-name))))) - (when vc-buffer - (setq buffer vc-buffer) - (puthash buffer-name buffer - diff-syntax-fontify-revisions)))) + (buffer (get-buffer buffer-name))) + (if buffer + ;; Don't re-initialize the buffer (which would throw + ;; away the previous fontification work). + (setq file nil) + (setq buffer (ignore-errors + (vc-find-revision-no-save + (expand-file-name file) revision + diff-vc-backend + (get-buffer-create buffer-name))))) (when buffer (with-current-buffer buffer (diff-syntax-fontify-props file text line-nb)))))))) diff --git a/lisp/vc/log-edit.el b/lisp/vc/log-edit.el index 42710dd8dc9..ba5a1a3d572 100644 --- a/lisp/vc/log-edit.el +++ b/lisp/vc/log-edit.el @@ -754,7 +754,9 @@ regardless of user name or time." (log-edit-insert-changelog-entries (log-edit-files))))) (log-edit-set-common-indentation) ;; Add an Author: field if appropriate. - (when author (log-edit-add-field "Author" (car author))) + (when author + (log-edit-add-field "Author" (car author)) + (log-edit-add-field "Summary" "")) ;; Add a Fixes: field if applicable. (when (consp log-edit-rewrite-fixes) (rfc822-goto-eoh) diff --git a/src/emacs.c b/src/emacs.c index 68835cac985..6ed4b0ed87a 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -157,9 +157,14 @@ static uprintmax_t heap_bss_diff; /* To run as a background daemon under Cocoa or Windows, we must do a fork+exec, not a simple fork. - On Cocoa, CoreFoundation lib fails in forked process: + On Cocoa, CoreFoundation lib fails in forked process, see Mac OS X + Leopard Developer Release Notes for CoreFoundation Framework: + http://developer.apple.com/ReleaseNotes/ - CoreFoundation/CoreFoundation.html) + CoreFoundation/CoreFoundation.html + + Note: the above is no longer available on-line, but it can be found + via the "Wayback machine", https://web.archive.org. On Windows, a Cygwin fork child cannot access the USER subsystem. diff --git a/src/json.c b/src/json.c index 5e1439f881a..74e0534065f 100644 --- a/src/json.c +++ b/src/json.c @@ -337,8 +337,14 @@ enum json_object_type { json_object_plist }; +enum json_array_type { + json_array_array, + json_array_list +}; + struct json_configuration { enum json_object_type object_type; + enum json_array_type array_type; Lisp_Object null_object; Lisp_Object false_object; }; @@ -521,7 +527,7 @@ static void json_parse_args (ptrdiff_t nargs, Lisp_Object *args, struct json_configuration *conf, - bool configure_object_type) + bool parse_object_types) { if ((nargs % 2) != 0) wrong_type_argument (Qplistp, Flist (nargs, args)); @@ -531,7 +537,7 @@ json_parse_args (ptrdiff_t nargs, for (ptrdiff_t i = nargs; i > 0; i -= 2) { Lisp_Object key = args[i - 2]; Lisp_Object value = args[i - 1]; - if (configure_object_type && EQ (key, QCobject_type)) + if (parse_object_types && EQ (key, QCobject_type)) { if (EQ (value, Qhash_table)) conf->object_type = json_object_hashtable; @@ -542,12 +548,22 @@ json_parse_args (ptrdiff_t nargs, else wrong_choice (list3 (Qhash_table, Qalist, Qplist), value); } + else if (parse_object_types && EQ (key, QCarray_type)) + { + if (EQ (value, Qarray)) + conf->array_type = json_array_array; + else if (EQ (value, Qlist)) + conf->array_type = json_array_list; + else + wrong_choice (list2 (Qarray, Qlist), value); + } else if (EQ (key, QCnull_object)) conf->null_object = value; else if (EQ (key, QCfalse_object)) conf->false_object = value; - else if (configure_object_type) - wrong_choice (list3 (QCobject_type, + else if (parse_object_types) + wrong_choice (list4 (QCobject_type, + QCarray_type, QCnull_object, QCfalse_object), value); @@ -604,7 +620,8 @@ usage: (json-serialize OBJECT &rest ARGS) */) } #endif - struct json_configuration conf = {json_object_hashtable, QCnull, QCfalse}; + struct json_configuration conf = + {json_object_hashtable, json_array_array, QCnull, QCfalse}; json_parse_args (nargs - 1, args + 1, &conf, false); json_t *json = lisp_to_json_toplevel (args[0], &conf); @@ -701,7 +718,8 @@ usage: (json-insert OBJECT &rest ARGS) */) } #endif - struct json_configuration conf = {json_object_hashtable, QCnull, QCfalse}; + struct json_configuration conf = + {json_object_hashtable, json_array_array, QCnull, QCfalse}; json_parse_args (nargs - 1, args + 1, &conf, false); json_t *json = lisp_to_json (args[0], &conf); @@ -817,10 +835,35 @@ json_to_lisp (json_t *json, struct json_configuration *conf) size_t size = json_array_size (json); if (PTRDIFF_MAX < size) overflow_error (); - Lisp_Object result = make_vector (size, Qunbound); - for (ptrdiff_t i = 0; i < size; ++i) - ASET (result, i, - json_to_lisp (json_array_get (json, i), conf)); + Lisp_Object result; + switch (conf->array_type) + { + case json_array_array: + { + result = make_vector (size, Qunbound); + for (ptrdiff_t i = 0; i < size; ++i) + { + rarely_quit (i); + ASET (result, i, + json_to_lisp (json_array_get (json, i), conf)); + } + break; + } + case json_array_list: + { + result = Qnil; + for (ptrdiff_t i = size - 1; i >= 0; --i) + { + rarely_quit (i); + result = Fcons (json_to_lisp (json_array_get (json, i), conf), + result); + } + break; + } + default: + /* Can't get here. */ + emacs_abort (); + } --lisp_eval_depth; return result; } @@ -905,18 +948,22 @@ json_to_lisp (json_t *json, struct json_configuration *conf) DEFUN ("json-parse-string", Fjson_parse_string, Sjson_parse_string, 1, MANY, NULL, doc: /* Parse the JSON STRING into a Lisp object. - This is essentially the reverse operation of `json-serialize', which -see. The returned object will be a vector, hashtable, alist, or +see. The returned object will be a vector, list, hashtable, alist, or plist. Its elements will be the JSON null value, the JSON false value, t, numbers, strings, or further vectors, hashtables, alists, or plists. If there are duplicate keys in an object, all but the last -one are ignored. If STRING doesn't contain a valid JSON object, an -error of type `json-parse-error' is signaled. The arguments ARGS are -a list of keyword/argument pairs: +one are ignored. If STRING doesn't contain a valid JSON object, this +function signals an error of type `json-parse-error'. + +The arguments ARGS are a list of keyword/argument pairs: The keyword argument `:object-type' specifies which Lisp type is used -to represent objects; it can be `hash-table', `alist' or `plist'. +to represent objects; it can be `hash-table', `alist' or `plist'. It +defaults to `hash-table'. + +The keyword argument `:array-type' specifies which Lisp type is used +to represent arrays; it can be `array' (the default) or `list'. The keyword argument `:null-object' specifies which object to use to represent a JSON null value. It defaults to `:null'. @@ -946,7 +993,8 @@ usage: (json-parse-string STRING &rest ARGS) */) Lisp_Object string = args[0]; Lisp_Object encoded = json_encode (string); check_string_without_embedded_nuls (encoded); - struct json_configuration conf = {json_object_hashtable, QCnull, QCfalse}; + struct json_configuration conf = + {json_object_hashtable, json_array_array, QCnull, QCfalse}; json_parse_args (nargs - 1, args + 1, &conf, true); json_error_t error; @@ -993,9 +1041,32 @@ json_read_buffer_callback (void *buffer, size_t buflen, void *data) DEFUN ("json-parse-buffer", Fjson_parse_buffer, Sjson_parse_buffer, 0, MANY, NULL, doc: /* Read JSON object from current buffer starting at point. -This is similar to `json-parse-string', which see. Move point after -the end of the object if parsing was successful. On error, point is -not moved. +Move point after the end of the object if parsing was successful. +On error, don't move point. + +The returned object will be a vector, list, hashtable, alist, or +plist. Its elements will be the JSON null value, the JSON false +value, t, numbers, strings, or further vectors, lists, hashtables, +alists, or plists. If there are duplicate keys in an object, all +but the last one are ignored. + +If the current buffer doesn't contain a valid JSON object, the +function signals an error of type `json-parse-error'. + +The arguments ARGS are a list of keyword/argument pairs: + +The keyword argument `:object-type' specifies which Lisp type is used +to represent objects; it can be `hash-table', `alist' or `plist'. It +defaults to `hash-table'. + +The keyword argument `:array-type' specifies which Lisp type is used +to represent arrays; it can be `array' (the default) or `list'. + +The keyword argument `:null-object' specifies which object to use +to represent a JSON null value. It defaults to `:null'. + +The keyword argument `:false-object' specifies which object to use to +represent a JSON false value. It defaults to `:false'. usage: (json-parse-buffer &rest args) */) (ptrdiff_t nargs, Lisp_Object *args) { @@ -1016,7 +1087,8 @@ usage: (json-parse-buffer &rest args) */) } #endif - struct json_configuration conf = {json_object_hashtable, QCnull, QCfalse}; + struct json_configuration conf = + {json_object_hashtable, json_array_array, QCnull, QCfalse}; json_parse_args (nargs, args, &conf, true); ptrdiff_t point = PT_BYTE; @@ -1095,10 +1167,12 @@ syms_of_json (void) Fput (Qjson_parse_string, Qside_effect_free, Qt); DEFSYM (QCobject_type, ":object-type"); + DEFSYM (QCarray_type, ":array-type"); DEFSYM (QCnull_object, ":null-object"); DEFSYM (QCfalse_object, ":false-object"); DEFSYM (Qalist, "alist"); DEFSYM (Qplist, "plist"); + DEFSYM (Qarray, "array"); defsubr (&Sjson_serialize); defsubr (&Sjson_insert); diff --git a/src/minibuf.c b/src/minibuf.c index a0025e22720..10fd5e56ac3 100644 --- a/src/minibuf.c +++ b/src/minibuf.c @@ -995,7 +995,8 @@ the current input method and the setting of`enable-multibyte-characters'. */) DEFUN ("read-command", Fread_command, Sread_command, 1, 2, 0, doc: /* Read the name of a command and return as a symbol. Prompt with PROMPT. By default, return DEFAULT-VALUE or its first element -if it is a list. */) +if it is a list. If DEFAULT-VALUE is omitted or nil, and the user enters +null input, return a symbol whose name is an empty string. */) (Lisp_Object prompt, Lisp_Object default_value) { Lisp_Object name, default_string; diff --git a/src/xfns.c b/src/xfns.c index 13f66f07183..e521ed12e40 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -5030,7 +5030,7 @@ Internal use only, use `display-monitor-attributes-list' instead. */) mi->mm_height = height_mm; #if GTK_CHECK_VERSION (3, 22, 0) - mi->name = xstrdup (gdk_monitor_get_model (monitor)); + dupstring (&mi->name, (gdk_monitor_get_model (monitor))); #elif GTK_CHECK_VERSION (2, 14, 0) mi->name = gdk_screen_get_monitor_plug_name (gscreen, i); #endif diff --git a/src/xterm.c b/src/xterm.c index 5aa3e3ff25c..def6915d62e 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -922,16 +922,17 @@ x_set_frame_alpha (struct frame *f) else alpha = f->alpha[1]; + if (alpha < 0.0) + return; + if (FLOATP (Vframe_alpha_lower_limit)) alpha_min = XFLOAT_DATA (Vframe_alpha_lower_limit); else if (FIXNUMP (Vframe_alpha_lower_limit)) alpha_min = (XFIXNUM (Vframe_alpha_lower_limit)) / 100.0; - if (alpha < 0.0) - return; - else if (alpha > 1.0) + if (alpha > 1.0) alpha = 1.0; - else if (0.0 <= alpha && alpha < alpha_min && alpha_min <= 1.0) + else if (alpha < alpha_min && alpha_min <= 1.0) alpha = alpha_min; opac = alpha * OPAQUE; diff --git a/test/lisp/filenotify-tests.el b/test/lisp/filenotify-tests.el index 50036209b0f..842d66d7780 100644 --- a/test/lisp/filenotify-tests.el +++ b/test/lisp/filenotify-tests.el @@ -266,9 +266,8 @@ This returns only for the local case and gfilenotify; otherwise it is nil. (declare (indent 1)) `(ert-deftest ,(intern (concat (symbol-name test) "-remote")) () ,docstring - :tags '(:expensive-test) :expected-result (or ,expected :passed) - (skip-unless (not ,skip)) + :tags ,(if skip ''(:expensive-test :unstable) ''(:expensive-test)) (let* ((temporary-file-directory file-notify-test-remote-temporary-file-directory) (ert-test (ert-get-test ',test)) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 5a9541db8fb..cc3200be948 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -4579,7 +4579,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." ;; skip the test then. (condition-case nil (vc-create-repo (car vc-handled-backends)) - (error (skip-unless nil))) + (error (ert-skip "`vc-create-repo' not supported"))) ;; The structure of VC-FILESET is not documented. Let's ;; hope it won't change. (condition-case nil diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el index 999cf8dc7a3..b940f45bb90 100644 --- a/test/lisp/progmodes/python-tests.el +++ b/test/lisp/progmodes/python-tests.el @@ -5350,7 +5350,7 @@ buffer with overlapping strings." ;; The description of the problem it's trying to catch is not clear enough ;; to be able to see if the underlying problem is really fixed, sadly. ;; E.g. I don't know what is meant by "overlap", really. - (skip-unless nil) + :tags '(:unstable) (python-tests-with-temp-buffer "''' '\n''' ' '\n" (syntax-propertize (point-max)) ;; Create a situation where strings nominally overlap. This diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index 7465aac5ea5..c458eef2f93 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -318,24 +318,6 @@ cf. Bug#25477." (should (eq (string-to-char (symbol-name (gensym))) ?g)) (should (eq (string-to-char (symbol-name (gensym "X"))) ?X))) -(ert-deftest subr-tests--proper-list-p () - "Test `proper-list-p' behavior." - (dotimes (length 4) - ;; Proper and dotted lists. - (let ((list (make-list length 0))) - (should (= (proper-list-p list) length)) - (should (not (proper-list-p (nconc list 0))))) - ;; Circular lists. - (dotimes (n (1+ length)) - (let ((circle (make-list (1+ length) 0))) - (should (not (proper-list-p (nconc circle (nthcdr n circle)))))))) - ;; Atoms. - (should (not (proper-list-p 0))) - (should (not (proper-list-p ""))) - (should (not (proper-list-p []))) - (should (not (proper-list-p (make-bool-vector 0 nil)))) - (should (not (proper-list-p (make-symbol "a"))))) - (ert-deftest subr-tests--assq-delete-all () "Test `assq-delete-all' behavior." (cl-flet ((new-list-fn diff --git a/test/src/fns-tests.el b/test/src/fns-tests.el index d6cc99e8e33..6ebab4287f7 100644 --- a/test/src/fns-tests.el +++ b/test/src/fns-tests.el @@ -648,4 +648,22 @@ (should (equal (list (eq a b) n len) (list t n len)))))))) +(ert-deftest test-proper-list-p () + "Test `proper-list-p' behavior." + (dotimes (length 4) + ;; Proper and dotted lists. + (let ((list (make-list length 0))) + (should (= (proper-list-p list) length)) + (should (not (proper-list-p (nconc list 0))))) + ;; Circular lists. + (dotimes (n (1+ length)) + (let ((circle (make-list (1+ length) 0))) + (should (not (proper-list-p (nconc circle (nthcdr n circle)))))))) + ;; Atoms. + (should (not (proper-list-p 0))) + (should (not (proper-list-p ""))) + (should (not (proper-list-p []))) + (should (not (proper-list-p (make-bool-vector 0 nil)))) + (should (not (proper-list-p (make-symbol "a"))))) + (provide 'fns-tests) diff --git a/test/src/json-tests.el b/test/src/json-tests.el index 04f91f4abbc..542eec11bf3 100644 --- a/test/src/json-tests.el +++ b/test/src/json-tests.el @@ -117,6 +117,14 @@ (should (equal (json-parse-string input :object-type 'plist) '(:abc [9 :false] :def :null))))) +(ert-deftest json-parse-string/array () + (skip-unless (fboundp 'json-parse-string)) + (let ((input "[\"a\", 1, [\"b\", 2]]")) + (should (equal (json-parse-string input) + ["a" 1 ["b" 2]])) + (should (equal (json-parse-string input :array-type 'list) + '("a" 1 ("b" 2)))))) + (ert-deftest json-parse-string/string () (skip-unless (fboundp 'json-parse-string)) (should-error (json-parse-string "[\"formfeed\f\"]") :type 'json-parse-error)