Merge remote-tracking branch 'savannah/master' into HEAD

This commit is contained in:
Andrea Corallo 2020-03-09 07:49:33 +00:00
commit 87ee6ff4eb
100 changed files with 2779 additions and 1272 deletions

File diff suppressed because it is too large Load diff

View file

@ -294,7 +294,10 @@ If REALNAME is nil, ignore that author.")
"preferences\\.\\(nib\\|gorm\\)"
;; Generated files that have since been removed.
"\\(refcard\\(-de\\|-pl\\)?\\|calccard\\|dired-ref\\|orgcard\\|\
gnus-booklet\\|fr-drdref\\)\\.p\\(df\\|s\\)\\'")
gnus-booklet\\|fr-drdref\\)\\.p\\(df\\|s\\)\\'"
;; Removed as obsolete
"README-ftp-server"
)
"List of regexps matching obsolete files.
Changes to files matching one of the regexps in this list are not listed.")
@ -459,6 +462,12 @@ Changes to files matching one of the regexps in this list are not listed.")
;; ada-mode has been deleted, now in GNU ELPA
"ada-mode.texi"
"GNUS-NEWS"
"doc/misc/gnus-news.el"
"src/fingerprint-dummy.c"
"src/fingerprint.h"
;; Replaced by lisp/thread.el
"lisp/emacs-lisp/thread-list.el"
"etc/images/slash.bmp"
)
"List of files and directories to ignore.
Changes to files in this list are not listed.")
@ -1103,6 +1112,8 @@ in the repository.")
("lisp/net/starttls.el" . "lisp/obsolete/starttls.el")
("url-ns.el" . "lisp/obsolete/url-ns.el")
("gnus-news.texi" . "doc/misc/gnus.texi")
("lisp/multifile.el". "lisp/fileloop.el")
("lisp/emacs-lisp/thread.el". "lisp/thread.el")
)
"Alist of files which have been renamed during their lifetime.
Elements are (OLDNAME . NEWNAME).")

View file

@ -34,7 +34,7 @@ GNULIB_MODULES='
d-type diffseq dosname double-slash-root dtoastr dtotimespec dup2
environ execinfo explicit_bzero faccessat
fchmodat fcntl fcntl-h fdopendir
filemode filevercmp flexmember fpieee fstatat fsusage fsync
filemode filevercmp flexmember fpieee fstatat fsusage fsync futimens
getloadavg getopt-gnu gettime gettimeofday gitlog-to-changelog
ieee754-h ignore-value intprops largefile lstat
manywarnings memmem-simple mempcpy memrchr minmax mkostemp mktime nstrftime
@ -43,7 +43,7 @@ GNULIB_MODULES='
sig2str socklen stat-time std-gnu11 stdalign stddef stdio
stpcpy strnlen strtoimax symlink sys_stat sys_time
tempname time time_r time_rz timegm timer-time timespec-add timespec-sub
update-copyright unlocked-io utimens
update-copyright unlocked-io utimensat
vla warnings
'

View file

@ -214,6 +214,7 @@ Select a buffer to be used by next invocation of @code{next-error} and
@kindex C-x `
@findex next-error
@vindex next-error-highlight
@vindex next-error-highlight-no-select
To visit errors sequentially, type @w{@kbd{C-x `}}
(@code{next-error}), or equivalently @kbd{M-g M-n} or @kbd{M-g n}.
This command can be invoked from any buffer, not just a Compilation
@ -258,7 +259,9 @@ to skip any messages.
When Emacs visits the locus of an error message, it momentarily
highlights the relevant source line. The duration of this highlight
is determined by the variable @code{next-error-highlight}.
is determined by the variable @code{next-error-highlight} for the locus
in the selected buffer, and @code{next-error-highlight-no-select} for
the locus in non-selected buffers.
@vindex compilation-context-lines
If the @file{*compilation*} buffer is shown in a window with a left

View file

@ -1873,15 +1873,19 @@ You can use a vector for the simple cases too:
Language and coding systems may cause problems with key bindings for
non-@acronym{ASCII} characters. @xref{Init Non-ASCII}.
@findex define-key
As described in @ref{Local Keymaps}, major modes and minor modes can
define local keymaps. These keymaps are constructed when the mode is
used for the first time in a session. If you wish to change one of
these keymaps, you must use the @dfn{mode hook} (@pxref{Hooks}).
loaded for the first time in a session. The function @code{define-key}
can be used to make changes in a specific keymap. This function can
also unset keys, when passed @code{nil} as the binding.
@findex define-key
For example, Texinfo mode runs the hook @code{texinfo-mode-hook}.
Here's how you can use the hook to add local bindings for @kbd{C-c n}
and @kbd{C-c p} in Texinfo mode:
Since a mode's keymaps are not constructed until it has been loaded,
you must delay running code which modifies them, e.g., by putting it
on a @dfn{mode hook} (@pxref{(Hooks)}). For example, Texinfo mode
runs the hook @code{texinfo-mode-hook}. Here's how you can use the
hook to add local bindings for @kbd{C-c n} and @kbd{C-c p}, and remove
the one for @kbd{C-c C-x x} in Texinfo mode:
@example
(add-hook 'texinfo-mode-hook
@ -1890,6 +1894,7 @@ and @kbd{C-c p} in Texinfo mode:
'backward-paragraph)
(define-key texinfo-mode-map "\C-cn"
'forward-paragraph)))
(define-key texinfo-mode-map "\C-c\C-xx" nil)
@end example
@node Modifier Keys

View file

@ -143,6 +143,64 @@ The variables for right-hand keys, like @code{ns-right-alternate-modifier},
may also be set to @code{left}, which means to use the same behavior as
the corresponding left-hand key.
@subsection Frame Variables
@table @code
@vindex ns-use-proxy-icon
@item ns-use-proxy-icon
This variable specifies whether to display the proxy icon in the
titlebar.
@vindex ns-confirm-quit
@item ns-confirm-quit
This variable specifies whether to display a graphical confirmation
dialogue on quitting.
@vindex ns-auto-hide-menu-bar
@item ns-auto-hide-menu-bar
This variable specifies whether the macOS menu bar is hidden when an
Emacs frame is selected. If non-nil the menu bar is not shown unless
the mouse pointer is moved near to the top of the screen.
@vindex ns-use-native-fullscreen
@item ns-use-native-fullscreen
This variable controls whether to use native, or non-native
fullscreen. Native fullscreen is only available on macOS 10.7 and
above.
@end table
@subsection macOS Trackpad/Mousewheel Variables
These variables only apply to macOS 10.7 (Lion) and above.
@table @code
@vindex ns-use-mwheel-acceleration
@item ns-use-mwheel-acceleration
This variable controls whether Emacs ignores the system mousewheel
acceleration. When nil each `click' of the mousewheel will correspond
exactly with one mousewheel event. When non-nil, the default, each
`click' may correspond with more than one mousewheel event, depending
on the user's input.
@vindex ns-use-mwheel-momentum
@item ns-use-mwheel-momentum
This variable controls whether Emacs ignores the system `momentum'
when scrolling using a trackpad. When non-nil, the default, scrolling
rapidly may result in the buffer continuing to scroll for a short
while after the user has lifted their fingers off the trackpad.
@vindex ns-mwheel-line-height
@item ns-mwheel-line-height
This variable controls the sensitivity of scrolling with the trackpad.
Apple trackpads scroll by pixels, not lines, so Emacs converts the
system's pixel values into lines. When set to a number, this variable
sets the number of pixels Emacs will consider as one line. When nil
or a non-number the default line height is used.
Setting a lower number makes the trackpad more sensitive, and a higher
number makes the trackpad less sensitive.
@end table
@subsection Font Panel
@findex ns-popup-font-panel
@ -153,17 +211,6 @@ recently used or clicked on.
@c To make the setting permanent, use @samp{Save Options} in the
@c Options menu, or run @code{menu-bar-options-save}.
@cindex Core Text, on macOS
@cindex font backend, on macOS
In macOS, Emacs uses a Core Text based font backend
by default. If you prefer the older font style, enter the following
at the command-line before starting Emacs:
@example
% defaults write org.gnu.Emacs FontBackend ns
@end example
@node Mac / GNUstep Events
@section Windowing System Events under macOS / GNUstep
@cindex events on macOS

View file

@ -813,35 +813,23 @@ varieties.
@cindex y or n prompt
For the first type of yes-or-no query, the prompt ends with
@samp{(y or n)}. Such a query does not actually use the minibuffer;
the prompt appears in the echo area, and you answer by typing either
@samp{y} or @samp{n}, which immediately delivers the response. For
example, if you type @kbd{C-x C-w} (@kbd{write-file}) to save a
buffer, and enter the name of an existing file, Emacs issues a prompt
like this:
@w{@samp{(y or n)}}. You answer the query by typing a single key,
either @samp{y} or @samp{n}, which immediately exits the minibuffer
and delivers the response. For example, if you type @kbd{C-x C-w}
(@kbd{write-file}) to save a buffer, and enter the name of an existing
file, Emacs issues a prompt like this:
@smallexample
File foo.el exists; overwrite? (y or n)
@end smallexample
@noindent
Because this query does not actually use the minibuffer, the usual
minibuffer editing commands cannot be used. However, you can perform
some window scrolling operations while the query is active: @kbd{C-l}
recenters the selected window; @kbd{C-v} (or @key{PageDown}, or
@key{next}) scrolls forward; @kbd{M-v} (or @key{PageUp}, or
@key{prior}) scrolls backward; @kbd{C-M-v} scrolls forward in the next
window; and @kbd{C-M-S-v} scrolls backward in the next window. Typing
@kbd{C-g} dismisses the query, and quits the command that issued it
(@pxref{Quitting}).
@cindex yes or no prompt
The second type of yes-or-no query is typically employed if
giving the wrong answer would have serious consequences; it uses the
minibuffer, and features a prompt ending with @samp{(yes or no)}. For
example, if you invoke @kbd{C-x k} (@code{kill-buffer}) on a
file-visiting buffer with unsaved changes, Emacs activates the
minibuffer with a prompt like this:
The second type of yes-or-no query is typically employed if giving
the wrong answer would have serious consequences; it thus features a
longer prompt ending with @samp{(yes or no)}. For example, if you
invoke @kbd{C-x k} (@code{kill-buffer}) on a file-visiting buffer with
unsaved changes, Emacs activates the minibuffer with a prompt like
this:
@smallexample
Buffer foo.el modified; kill anyway? (yes or no)
@ -849,7 +837,12 @@ Buffer foo.el modified; kill anyway? (yes or no)
@noindent
To answer, you must type @samp{yes} or @samp{no} into the minibuffer,
followed by @key{RET}. The minibuffer behaves as described in the
previous sections; you can switch to another window with @kbd{C-x o},
use the history commands @kbd{M-p} and @kbd{M-n}, etc. Type @kbd{C-g}
to quit the minibuffer and the querying command.
followed by @key{RET}.
With both types of yes-or-no query the minibuffer behaves as described
in the previous sections; you can recenter the selected window with
@kbd{C-l}, scroll that window (@kbd{C-v} or @kbd{PageDown} scrolls
forward, @kbd{M-v} or @kbd{PageUp} scrolls backward), switch to
another window with @kbd{C-x o}, use the history commands @kbd{M-p}
and @kbd{M-n}, etc. Type @kbd{C-g} to dismiss the query, and quit the
minibuffer and the querying command (@pxref{Quitting}).

View file

@ -302,7 +302,7 @@ function is called, it reads the full definition from the file, to
replace the place-holder.
The advantage of dynamic function loading is that loading the file
becomes much faster. This is a good thing for a file which contains
should become faster. This is a good thing for a file which contains
many separate user-callable functions, if using one of them does not
imply you will probably also use the rest. A specialized mode which
provides many keyboard commands often has that usage pattern: a user may
@ -326,6 +326,10 @@ installed Emacs files. But they are quite likely to happen with Lisp
files that you are changing. The easiest way to prevent these problems
is to reload the new compiled file immediately after each recompilation.
@emph{Experience shows that using dynamic function loading provides
benefits that are hardly measurable, so this feature is deprecated
since Emacs 27.1.}
The byte compiler uses the dynamic function loading feature if the
variable @code{byte-compile-dynamic} is non-@code{nil} at compilation
time. Do not set this variable globally, since dynamic loading is

View file

@ -1909,11 +1909,19 @@ omitted or @code{nil}, it defaults to 0, i.e., no access rights at
all.
@end defun
@defun set-file-times filename &optional time
@defun set-file-times filename &optional time flag
This function sets the access and modification times of @var{filename}
to @var{time}. The return value is @code{t} if the times are successfully
set, otherwise it is @code{nil}. @var{time} defaults to the current
time and must be a time value (@pxref{Time of Day}).
By default this function follows symbolic links. However, if the
optional argument @var{flag} is the symbol @code{nofollow}, this
function does not follow @var{filename} if it is a symbolic link;
this can help prevent inadvertently changing the times of a file
somewhere else. On platforms that do not support changing times
on a symbolic link, this function signals an error when @var{filename}
is a symbolic link and @var{flag} is @code{nofollow}.
@end defun
@defun set-file-extended-attributes filename attribute-alist

View file

@ -3264,7 +3264,7 @@ that deletion fails for whatever reason, the child frame is made a
top-level frame.
Whether a child frame can have a menu or tool bar is window-system or
window manager dependent. Most window-systems explicitly disallow menus
window manager dependent. Most window-systems explicitly disallow menu
bars for child frames. It seems advisable to disable both, menu and
tool bars, via the frame's initial parameters settings.

View file

@ -2236,16 +2236,16 @@ the end of @var{question}. The possible responses are provided in
@noindent
where @var{long-answer} is the complete text of the user response, a
string; @var{short-answer} is a short form of the same response, a
single character; and @var{help-message} is the text that describes
the meaning of the answer. If the variable @code{read-answer-short}
is non-@code{nil}, the prompt will show the short variants of the
possible answers and the user is expected to type the single
characters shown in the prompt; otherwise the prompt will show the
long variants of the answers, and the user is expected to type the
full text of one of the answers and end by pressing @key{RET}. If
@code{use-dialog-box} is non-@code{nil}, and this function was invoked
by mouse events, the question and the answers will be displayed in a
GUI dialog box.
single character or a function key; and @var{help-message} is the text
that describes the meaning of the answer. If the variable
@code{read-answer-short} is non-@code{nil}, the prompt will show the
short variants of the possible answers and the user is expected to
type the single characters/keys shown in the prompt; otherwise the
prompt will show the long variants of the answers, and the user is
expected to type the full text of one of the answers and end by
pressing @key{RET}. If @code{use-dialog-box} is non-@code{nil}, and
this function was invoked by mouse events, the question and the
answers will be displayed in a GUI dialog box.
The function returns the text of the @var{long-answer} selected by the
user, regardless of whether long or short answers were shown in the

View file

@ -1979,10 +1979,9 @@ The result is @code{nil} if either argument is a NaN.
@defun time-subtract t1 t2
This returns the time difference @var{t1} @minus{} @var{t2} between
two time values, normally as a Lisp timestamp but as a float
if either argument is infinite or a NaN@.
When the result is a timestamp, it is exact and its clock
two time values, as a Lisp time value. The result is exact and its clock
resolution is no worse than the worse of its two arguments' resolutions.
The result is floating-point only if it is infinite or a NaN.
If you need the difference in units
of elapsed seconds, you can convert it with @code{time-convert} or
@code{float-time}. @xref{Time Conversion}.

View file

@ -1086,8 +1086,9 @@ Corresponding string regexp: @samp{@var{A}@var{B}@dots{}}
@itemx @code{(| @var{rx}@dots{})}
@cindex @code{|} in rx
Match exactly one of the @var{rx}s.
If all arguments are string literals, the longest possible match
will always be used. Otherwise, either the longest match or the
If all arguments are strings, characters, or @code{or} forms
so constrained, the longest possible match will always be used.
Otherwise, either the longest match or the
first (in left-to-right order) will be used.
Without arguments, the expression will not match anything at all.@*
Corresponding string regexp: @samp{@var{A}\|@var{B}\|@dots{}}.

View file

@ -1076,7 +1076,7 @@ package is only activated if all its dependencies have been).
Its format is a list of lists on a single line. The @code{car} of
each sub-list is the name of a package, as a symbol. The @code{cadr}
of each sub-list is the minimum acceptable version number, as a string
that can be parse by @code{version-to-list}. An entry that lacks a
that can be parsed by @code{version-to-list}. An entry that lacks a
version (i.e., an entry which is just a symbol, or a sub-list of one
element) is equivalent to entry with version "0". For instance:

View file

@ -858,7 +858,7 @@ is a buffer if the buffer-local value of the variable is being
changed, @code{nil} otherwise.
@end defun
@defun remove-variable-watch symbol watch-function
@defun remove-variable-watcher symbol watch-function
This function removes @var{watch-function} from @var{symbol}'s list of
watchers.
@end defun
@ -1187,8 +1187,14 @@ When evaluating Emacs Lisp code directly using an @code{eval} call,
lexical binding is enabled if the @var{lexical} argument to
@code{eval} is non-@code{nil}. @xref{Eval}.
Lexical binding is also enabled in Lisp Interaction and IELM
mode, used in the @file{*scratch*} and @file{*ielm*} buffers.
@findex eval-expression@r{, and }lexical-binding
Lexical binding is also enabled in Lisp Interaction and IELM mode,
used in the @file{*scratch*} and @file{*ielm*} buffers, and also when
evaluating expressions via @kbd{M-:} (@code{eval-expression}) and when
processing the @option{--eval} command-line options of Emacs
(@pxref{Action Arguments,,, emacs, The GNU Emacs Manual}) and
@command{emacsclient} (@pxref{emacsclient Options,,, emacs, The GNU
Emacs Manual}).
@cindex special variables
Even when lexical binding is enabled, certain variables will

View file

@ -350,11 +350,12 @@ Line-Up Functions
* Misc Line-Up::
Customizing Macros
Custom Macros
* Macro Backslashes::
* Macros with ;::
* Noise Macros::
* Indenting Directives::
@end detailmenu
@end menu
@ -6949,6 +6950,10 @@ is @code{nil}, all lines inside macro definitions are analyzed as
@code{cpp-macro-cont}.
@end defopt
Sometimes you may want to indent particular directives
(e.g. @code{#pragma}) as though they were statements. To do this, see
@ref{Indenting Directives}.
Because a macro can expand into anything at all, near where one is
invoked @ccmode{} can only indent and fontify code heuristically.
Sometimes it gets it wrong. Usually you should try to design your
@ -6965,6 +6970,7 @@ Macros}.
* Macro Backslashes::
* Macros with ;::
* Noise Macros::
* Indenting Directives::
@end menu
@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@ -7074,7 +7080,7 @@ initialization code, after the mode hooks have run.
@end defun
@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@node Noise Macros, , Macros with ;, Custom Macros
@node Noise Macros, Indenting Directives, Macros with ;, Custom Macros
@comment node-name, next, previous, up
@section Noise Macros
@cindex noise macros
@ -7130,6 +7136,48 @@ has run. This function is called by @ccmode{}'s initialization code,
after the mode hooks have run.
@end defun
@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@node Indenting Directives, , Noise Macros, Custom Macros
@comment node-name, next, previous, up
@section Indenting Directives
@cindex Indenting Directives
@cindex Indenting #pragma
@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Sometimes you may want to indent particular preprocessor directives
(e.g. @code{#pragma}) as though they were statements. To do this,
first set up @code{c-cpp-indent-to-body-directives} to include the
directive name(s), then enable the ``indent to body'' feature with
@code{c-toggle-cpp-indent-to-body}.
@defopt c-cpp-indent-to-body-directives
@vindex cpp-indent-to-body-directives (c-)
This variable is a list of names of CPP directives (not including the
introducing @samp{#}) which will be indented as though statements.
Each element is a string, and must be a valid identifier. The default
value is @code{("pragma")}.
If you add more directives to this variable, or remove directives from
it, whilst ``indent to body'' is active, you need to re-enable the
feature by calling @code{c-toggle-cpp-indent-to-body} for these
changes to take effect@footnote{Note that the removal of directives
doesn't work satisfactorally on XEmacs or on very old versions of
Emacs}.
@end defopt
@defun c-toggle-cpp-indent-to-body
@findex toggle-cpp-indent-to-body (c-)
With @kbd{M-x c-toggle-cpp-indent-to-body}, you enable or disable the
``indent to body'' feature. When called programmatically, it takes an
optional numerical argument. A positive value will enable the
feature, a zero or negative value will disable it.
You should set up @code{c-cpp-indent-to-body-directives} before
calling this function, since the function sets internal state which
depends on that variable.
@end defun
@comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@node Odds and Ends, Sample Init File, Custom Macros, Top
@comment node-name, next, previous, up

View file

@ -1285,9 +1285,9 @@ This class is defined in the package @file{eieio-base}.
Sometimes it is useful to keep a master list of all instances of a given
class. The class @code{eieio-instance-tracker} performs this task.
@deftp {Class} eieio-instance-tracker tracker-symbol
@deftp {Class} eieio-instance-tracker tracking-symbol
Enable instance tracking for this class.
The slot @var{tracker-symbol} should be initialized in inheritors of
The slot @var{tracking-symbol} should be initialized in inheritors of
this class to a symbol created with @code{defvar}. This symbol will
serve as the variable used as a master list of all objects of the given
class.

View file

@ -3181,7 +3181,7 @@ For example:
(broken-reply-to . t))))
@end lisp
All clauses that matches the group name will be used, but the last
All clauses that match the group name will be used, but the last
setting ``wins''. So if you have two clauses that both match the
group name, and both set, say @code{display}, the last setting will
override the first.
@ -17874,7 +17874,7 @@ presence of 7 special headers. These headers are of the form
@code{X-Diary-<something>}, @code{<something>} being one of
@code{Minute}, @code{Hour}, @code{Dom}, @code{Month}, @code{Year},
@code{Time-Zone} and @code{Dow}. @code{Dom} means ``Day of Month'', and
@code{dow} means ``Day of Week''. These headers actually behave like
@code{Dow} means ``Day of Week''. These headers actually behave like
crontab specifications and define the event date(s):
@itemize @bullet
@ -30916,7 +30916,7 @@ description = <string>
Believe it or not, but some people who use Gnus haven't really used
Emacs much before they embarked on their journey on the Gnus Love Boat.
If you are one of those unfortunates whom ``@kbd{C-M-a}'', ``kill the
If you are one of those unfortunates to whom ``@kbd{C-M-a}'', ``kill the
region'', and ``set @code{gnus-flargblossen} to an alist where the key
is a regexp that is used for matching on the group name'' are magical
phrases with little or no meaning, then this appendix is for you. If

File diff suppressed because it is too large Load diff

View file

@ -739,9 +739,9 @@ stepping, you will see where the loop starts and ends. Also, examine
the data being used in the loop and try to determine why the loop does
not exit when it should.
On GNU and Unix systems, you can also trying sending Emacs SIGUSR2,
On GNU and Unix systems, you can also try sending Emacs SIGUSR2,
which, if 'debug-on-event' has its default value, will cause Emacs to
attempt to break it out of its current loop and into the Lisp
attempt to break out of its current loop and enter the Lisp
debugger. (See the node "Debugging" in the ELisp manual for the
details about the Lisp debugger.) This feature is useful when a
C-level debugger is not conveniently available.

View file

@ -225,8 +225,8 @@ called when the function object is garbage-collected. Use
'set_function_finalizer' to set the finalizer and
'get_function_finalizer' to retrieve it.
** 'file-modes' and 'set-file-modes' now have an optional argument
specifying whether to follow symbolic links.
** 'file-modes', 'set-file-modes', and 'set-file-times' now have an
optional argument specifying whether to follow symbolic links.
** 'parse-time-string' can now parse ISO 8601 format strings,
such as "2020-01-15T16:12:21-08:00".

View file

@ -347,14 +347,18 @@ The default value is 30000, as the previously hard-coded threshold.
+++
** The function 'read-passwd' uses "*" as default character to hide passwords.
+++
** The function 'read-answer' now accepts not only single character
answers, but also function keys like 'F1', character events such as
'C-M-h', and control characters like 'C-h'.
** Lexical binding is now used when evaluating interactive Elisp forms.
More specifically, 'lexical-binding' is now used for 'M-:', '--eval',
as well as in 'lisp-interaction-mode' and 'ielm-mode', used in the
"*scratch*" and "*ielm*" buffers.
+++
** Lexical binding is now used by default when evaluating interactive Elisp.
More specifically, 'lexical-binding' is now used by default for 'M-:'
and '--eval' (including in evaluations invoked from 'emacsclient' via
its '--eval' command-line option), as well as in
'lisp-interaction-mode' and 'ielm-mode', used in the "*scratch*" and
"*ielm*" buffers.
---
** The new user option 'tooltip-resize-echo-area' avoids truncating
@ -489,6 +493,7 @@ matches strings where the pattern appears as a subsequence. Put
simply, makes "foo" complete to both "barfoo" and "frodo". Add 'flex'
to 'completion-styles' or 'completion-category-overrides' to use it.
---
** The 'completion-common-part' face is now visible by default.
+++
@ -555,6 +560,7 @@ mode, they are described in the manual "(emacs) Display".
** New user option 'xref-file-name-display' controls the display of
file names in xref buffers.
---
** New user option 'byte-count-to-string-function'.
It is used for displaying file sizes and disk space in some cases.
@ -586,6 +592,7 @@ The HIST argument of 'read-from-minibuffer' now works correctly with
buffer-local variables. This means that different buffers can have
their own separated input history list if desired.
+++
** 'backup-by-copying-when-privileged-mismatch' applies to file gid, too.
In addition to checking the file owner uid, Emacs also checks that the
group gid is not greater than 'backup-by-copying-when-privileged-mismatch';
@ -739,9 +746,11 @@ non-nil.
what they're named, and the 'battery-linux-sysfs-regexp' variable has
been removed.
---
** The 'list-processes' command now includes port numbers in the
network connection information (in addition to the host name).
---
** The 'cl' package is now officially deprecated in favor of 'cl-lib'.
---
@ -750,51 +759,55 @@ network connection information (in addition to the host name).
*** When called interactively with a prefix arg 'C-u', 'desktop-read'
now prompts the user for the directory containing the desktop file.
+++
** display-line-numbers-mode
+++
*** New faces 'line-number-major-tick' and 'line-number-minor-tick',
and user options 'display-line-numbers-major-tick' and
'display-line-numbers-minor-tick' can be used to highlight the line
numbers of lines multiple of certain numbers.
+++
*** New variable 'display-line-numbers-offset', when non-zero, adds
an offset to absolute line numbers.
+++
** winner
+++
*** A new user option, 'winner-boring-buffers-regexp', has been added.
** table
*** 'table-generate-source' and friends now support outputting wiki and
mediawiki format tables.
+++
*** 'table-generate-source' now supports wiki and mediawiki
This command can now output wiki and mediawiki format tables.
---
** telnet-mode
---
*** Reverting a buffer in 'telnet-mode' will restart a closed connection.
** goto-addr
---
*** A way to more conveniently specify what URI address schemes should
be ignored has been added via the 'goto-address-uri-schemes-ignored'
variable.
+++
** tex-mode
+++
*** 'latex-noindent-commands' controls indentation of certain commands.
You can use this new user option to control indentation of arguments of
\emph, \footnote, and similar commands.
** byte compiler
+++
*** 'byte-compile-dynamic' is now obsolete.
This is because on the one hand it suffers from misbehavior in corner
cases that have plagued it for years, and on the other experiments indicated
that it doesn't bring any measurable benefit.
cases that have plagued it for years, and on the other hand experience
indicates that it doesn't bring any measurable benefit.
---
*** The 'g' keystroke in "*Compile-Log*" buffers has been bound to a
@ -832,15 +845,19 @@ its functions.
** doc-view.el
---
*** New commands 'doc-view-presentation' and 'doc-view-fit-window-to-page'.
---
*** Added support for password-protected PDF files.
---
*** A new user option 'doc-view-pdftotext-program-args' has been added
to allow controlling how the conversion to text is done.
** Ido
---
*** New user option 'ido-big-directories' to mark directories whose
names match certain regular expressions as big. Ido won't attempt to
list the contents of such directories when completing file names.
@ -871,6 +888,7 @@ at the end of the active minibuffer.
*** Some commands that previously used 'read-char-choice' now read
a character using the minibuffer by 'read-char-from-minibuffer'.
---
** map.el
*** Now also understands plists.
@ -882,6 +900,7 @@ a character using the minibuffer by 'read-char-from-minibuffer'.
+++
*** The 'type' arg can be a list '(hash-table :key1 VAL1 :key2 VAL2 ...)'.
---
** seq.el
New convenience functions 'seq-first' and 'seq-rest' give easy access
to respectively the first and all but the first elements of sequences.
@ -941,6 +960,7 @@ functions 'windmove-coord-add', 'windmove-constrain-to-range',
'windmove-constrain-loc-for-movement', 'windmove-wrap-loc-for-movement',
'windmove-reference-loc' and 'windmove-other-window-loc'.
---
** Octave mode
The mode is automatically enabled in files that start with the
'function' keyword.
@ -1103,9 +1123,11 @@ for a revision.
*** 'C-u C-x v D' ('vc-root-version-diff') prompts for two revisions
and compares their entire trees.
---
*** New user option 'vc-hg-revert-switches'.
It specifies switches to pass to Hg's 'revert' command.
---
*** 'C-x v M D' ('vc-diff-mergebase') and 'C-x v M L' ('vc-log-mergebase')
print diffs and logs between the merge base (common ancestor) of two
given revisions.
@ -1475,9 +1497,9 @@ strings and report all the spelling mistakes.
+++
*** New minor mode Fido mode.
This mode is based on Icomplete, and its name stands for "Fake Ido".
The point of this mode is to be an 'ido-mode' workalike, but provide
most of the functionality present in Icomplete that is not in
'ido-mode', while being much more compatible with all of Emacs's
The point of this mode is to be an 'ido-mode' workalike, providing
most of the functionality present in 'ido-mode' that is not in
Icomplete, which is much more compatible with all of Emacs's
completion facilities.
** Ecomplete
@ -1809,7 +1831,6 @@ keyboard macros.
'isearch-yank-symbol-or-char'. 'isearch-del-char' is now bound to
'C-M-d'.
+++
'M-s h l' invokes 'highlight-lines-matching-regexp' using the search
string to highlight lines matching the search string. This is similar
to the existing binding 'M-s h r' ('highlight-regexp') that highlights
@ -1964,6 +1985,7 @@ This is useful for games where lower scores are better, like time-based games.
*** Completing file names in the minibuffer via 'C-TAB' now uses the
styles as configured by the user option 'completion-styles'.
+++
** New macros 'thunk-let' and 'thunk-let*'.
These macros are analogue to 'let' and 'let*', but create bindings that
are evaluated lazily.
@ -2187,8 +2209,9 @@ are formatted as MIME digests.
*** 'message-forward-included-headers' has changed its default to
exclude most headers when forwarding.
---
*** 'mml-secure-openpgp-sign-with-sender' sets also "gpg --sender".
When 'mml-secure-openpgp-sign-with-sender' is non-nil message sender's
When 'mml-secure-openpgp-sign-with-sender' is non-nil, message sender's
email address (in addition to its old behavior) will also be used to
set gpg's "--sender email@domain" option.
@ -2323,7 +2346,16 @@ With 'or' and 'not', it can be used to compose character-matching
expressions from simpler parts.
+++
*** 'not' argument can now be a character or single-char string.
*** 'not' now accepts more argument types.
The argument can now also be a character, a single-character string,
an 'intersection' form, or an 'or' form whose arguments each match a
single character.
+++
*** Nested 'or' forms of strings guarantee a longest match.
For example, '(or (or "IN" "OUT") (or "INPUT" "OUTPUT"))' now matches
the whole string "INPUT" if present, not just "IN". Previously, this
was only guaranteed inside a single 'or' form of string literals.
** Frames
@ -2631,6 +2663,7 @@ overrides all system and Emacs-provided defaults. To get the old
method back, set 'mailcap-prefer-mailcap-viewers' to nil.
** MH-E
+++
*** The hook 'mh-show-mode-hook' is now called before the message is inserted.
Functions that want to affect the message text (for example, to change
@ -3075,6 +3108,7 @@ with POSIX.1-2017.
'decoded-time-weekday', 'decoded-time-dst' and 'decoded-time-zone'
accessors can be used.
+++
*** The new functions 'date-days-in-month' (which will say how many
days there are in a month in a specific year), 'date-ordinal-to-time'
(that computes the date of an ordinal day), 'decoded-time-add' (for
@ -3134,6 +3168,7 @@ throughput of reading from sub-processes that produces vast
** The new user option 'quit-window-hook' is now run first when
executing the 'quit-window' command.
+++
** The user options 'help-enable-completion-auto-load',
'help-enable-auto-load' and 'vhdl-project-auto-load', as well as the
function 'vhdl-auto-load-project' have been renamed to have "autoload"
@ -3614,15 +3649,18 @@ signal 'user-error' if there is no buffer to switch to.
** Battery status is now supported in all Cygwin builds.
Previously it was supported only in the Cygwin-w32 build.
---
** Emacs now handles key combinations involving the macOS "command"
and "option" modifier keys more correctly.
+++
** MacOS modifier key behavior is now more adjustable.
The behavior of the macOS "Option", "Command", "Control" and
"Function" keys can now be specified separately for use with
ordinary keys, function keys and mouse clicks. This allows using them
in their standard macOS way for composing characters.
+++
** The special handling of 'frame-title-format' on NS where setting it
to t would enable the macOS proxy icon has been replaced with a
separate variable, 'ns-use-proxy-icon'. 'frame-title-format' will now
@ -3673,6 +3711,7 @@ modifier keys in line with Apples guidelines. This makes the drag and
drop behavior more consistent, as previously the sending application
was able to 'set' modifiers without the knowledge of the user.
---
** On NS multicolor font display is enabled again since it is also
implemented in Emacs on free operating systems via Cairo drawing.

View file

@ -244,6 +244,23 @@ populate composition-function-table with those rules. See
composite.el for examples of this, and also grep lisp/language/*.el
for references to composition-function-table.
One problem with character compositions that will need to be solved is
that composition-function-table, the char-table which holds the
composition rules, is a global variable, whereas use of ligatures is
inherently specific to buffer-local stuff like the major mode and the
script or language in use. So there should be a buffer-local variable
to augment/customize/override the global composition rules.
Another problem is that ligatures are frequently composed of ASCII
characters, and some of those ASCII characters are present in the mode
line, for example "--". Since displaying a ligature instead of 2
separate '-' characters on a mode line is not right, there should be a
way of preventing the ligation from happening. One possibility is to
have a ZWNJ character separate these ASCII characters; another
possibility is to introduce a special text property that prevents
character composition, and place that property on the relevant parts
of the mode line.
The prettify-symbols-mode should be deprecated once ligature support
is in place.
@ -267,6 +284,60 @@ should invoke the 'shape' method. 'hbfont_shape' should be extended
to pass to 'hb_shape_full' the required array of features, as
mentioned in the above HarfBuzz discussion.
** Better support for displaying Emoji
Emacs is capable of displaying Emoji and some of the Emoji sequences,
provided that its fontsets are configured with a suitable font. To
make this easier out of the box, the following should be done:
*** Populate composition-function-table with Emoji rules
The Unicode Character Database (UCD) includes several data files that
define the valid Emoji sequences. These files should be imported into
the Emacs tree, and should be converted by some script at Emacs build
time to Lisp code that populates composition-function-table with the
corresponding composition rules.
*** Augment the default fontsets with Emoji-capable fonts
The default fontsets set up by fontest.el should include known free
fonts that provide good support for displaying Emoji sequences. In
addition, the rule that the default face's font is used for symbol and
punctuation characters, disregarding the fontsets, should be modified
to exempt Emoji from this rule (since Emoji characters belong to the
'symbol' script in Emacs), so that use-default-font-for-symbols would
not have to be tweaked to have Emoji display by default with a capable
font.
*** Consider changing the default display of Variation Selectors
Emacs by default displays the Variation Selector (VS) codepoints not
composed with base characters as hex codes in a box. The Unicode FAQ
says that if variation sequences cannot be supported, the VS
characters should not be shown, leaving just the base character of the
sequence visible. This could be handled via glyphless-char-display,
by changing the entries for VS codepoints to 'zero-width'. Or we
could display them as a thin 1-pixel space, as we do with format
control characters, by using 'thin-space' there.
*** Special face for displaying text presentation of Emoji
Emoji-capable fonts support Emoji sequences with the U+FE0F VARIATION
SELECTOR-16 (VS16) for emoji-style display, but usually don't support
the U+FE0F VARIATION SELECTOR-15 (VS15) for text-style display. There
are other fonts which support the text-style sequences, but not
emoji-style. Since Emacs selects a font based on a single character,
it cannot choose 2 different fonts for displaying both styles of the
same base character. To display both styles in the same buffer, one
could use a special face, placing a 'face' text property on portions
of the text. This special face could specify a specific font known to
support text-style Emoji sequences. Emacs could have such a face
built-in.
See the discussion of bug#39799 for more details about this task.
Another relevant resource is the Unicode Technical Standard #51
"Unicode Emoji" (http://www.unicode.org/reports/tr51/).
** Extend text-properties and overlays
*** Several text-property planes
This would get us rid of font-lock-face property (and I'd be happy to

View file

@ -124,6 +124,7 @@ University of California, as described above. */
#include <binary-io.h>
#include <intprops.h>
#include <unlocked-io.h>
#include <verify.h>
#include <c-ctype.h>
#include <c-strcase.h>
@ -7310,6 +7311,8 @@ static void *
xnmalloc (ptrdiff_t nitems, ptrdiff_t item_size)
{
ptrdiff_t nbytes;
assume (0 <= nitems);
assume (0 < item_size);
if (INT_MULTIPLY_WRAPV (nitems, item_size, &nbytes))
memory_full ();
return xmalloc (nbytes);
@ -7319,6 +7322,8 @@ static void *
xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size)
{
ptrdiff_t nbytes;
assume (0 <= nitems);
assume (0 < item_size);
if (INT_MULTIPLY_WRAPV (nitems, item_size, &nbytes) || SIZE_MAX < nbytes)
memory_full ();
void *result = realloc (pa, nbytes);

37
lib/futimens.c Normal file
View file

@ -0,0 +1,37 @@
/* Set the access and modification time of an open fd.
Copyright (C) 2009-2020 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 <https://www.gnu.org/licenses/>. */
/* written by Eric Blake */
#include <config.h>
#include <sys/stat.h>
#include "utimens.h"
/* Set the access and modification timestamps of FD to be
TIMESPEC[0] and TIMESPEC[1], respectively.
Fail with ENOSYS on systems without futimes (or equivalent).
If TIMESPEC is null, set the timestamps to the current time.
Return 0 on success, -1 (setting errno) on failure. */
int
futimens (int fd, struct timespec const times[2])
{
/* fdutimens also works around bugs in native futimens, when running
with glibc compiled against newer headers but on a Linux kernel
older than 2.6.32. */
return fdutimens (fd, NULL, times);
}

View file

@ -106,6 +106,7 @@
# fstatat \
# fsusage \
# fsync \
# futimens \
# getloadavg \
# getopt-gnu \
# gettime \
@ -155,7 +156,7 @@
# timespec-sub \
# unlocked-io \
# update-copyright \
# utimens \
# utimensat \
# vla \
# warnings
@ -1087,6 +1088,7 @@ gl_GNULIB_ENABLED_lchmod = @gl_GNULIB_ENABLED_lchmod@
gl_GNULIB_ENABLED_malloca = @gl_GNULIB_ENABLED_malloca@
gl_GNULIB_ENABLED_open = @gl_GNULIB_ENABLED_open@
gl_GNULIB_ENABLED_strtoll = @gl_GNULIB_ENABLED_strtoll@
gl_GNULIB_ENABLED_utimens = @gl_GNULIB_ENABLED_utimens@
gl_LIBOBJS = @gl_LIBOBJS@
gl_LTLIBOBJS = @gl_LTLIBOBJS@
gltests_LIBOBJS = @gltests_LIBOBJS@
@ -1733,6 +1735,17 @@ EXTRA_libgnu_a_SOURCES += fsync.c
endif
## end gnulib module fsync
## begin gnulib module futimens
ifeq (,$(OMIT_GNULIB_MODULE_futimens))
EXTRA_DIST += futimens.c
EXTRA_libgnu_a_SOURCES += futimens.c
endif
## end gnulib module futimens
## begin gnulib module getdtablesize
ifeq (,$(OMIT_GNULIB_MODULE_getdtablesize))
@ -3375,13 +3388,26 @@ endif
## begin gnulib module utimens
ifeq (,$(OMIT_GNULIB_MODULE_utimens))
ifneq (,$(gl_GNULIB_ENABLED_utimens))
libgnu_a_SOURCES += utimens.c
endif
EXTRA_DIST += utimens.h
endif
## end gnulib module utimens
## begin gnulib module utimensat
ifeq (,$(OMIT_GNULIB_MODULE_utimensat))
EXTRA_DIST += at-func.c utimensat.c
EXTRA_libgnu_a_SOURCES += at-func.c utimensat.c
endif
## end gnulib module utimensat
## begin gnulib module verify
ifeq (,$(OMIT_GNULIB_MODULE_verify))

View file

@ -110,7 +110,9 @@ open (const char *filename, int flags, ...)
directories,
- if O_WRONLY or O_RDWR is specified, open() must fail because the
file does not contain a '.' directory. */
if (flags & (O_CREAT | O_WRONLY | O_RDWR))
if ((flags & O_CREAT)
|| (flags & O_ACCMODE) == O_RDWR
|| (flags & O_ACCMODE) == O_WRONLY)
{
size_t len = strlen (filename);
if (len > 0 && filename[len - 1] == '/')

160
lib/utimensat.c Normal file
View file

@ -0,0 +1,160 @@
/* Set the access and modification time of a file relative to directory fd.
Copyright (C) 2009-2020 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 <https://www.gnu.org/licenses/>. */
/* written by Eric Blake */
#include <config.h>
/* Specification. */
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include "stat-time.h"
#include "timespec.h"
#include "utimens.h"
#if HAVE_UTIMENSAT
# undef utimensat
/* If we have a native utimensat, but are compiling this file, then
utimensat was defined to rpl_utimensat by our replacement
sys/stat.h. We assume the native version might fail with ENOSYS,
or succeed without properly affecting ctime (as is the case when
using newer glibc but older Linux kernel). In this scenario,
rpl_utimensat checks whether the native version is usable, and
local_utimensat provides the fallback manipulation. */
static int local_utimensat (int, char const *, struct timespec const[2], int);
# define AT_FUNC_NAME local_utimensat
/* Like utimensat, but work around native bugs. */
int
rpl_utimensat (int fd, char const *file, struct timespec const times[2],
int flag)
{
# if defined __linux__ || defined __sun
struct timespec ts[2];
# endif
/* See comments in utimens.c for details. */
static int utimensat_works_really; /* 0 = unknown, 1 = yes, -1 = no. */
if (0 <= utimensat_works_really)
{
int result;
# if defined __linux__ || defined __sun
struct stat st;
/* As recently as Linux kernel 2.6.32 (Dec 2009), several file
systems (xfs, ntfs-3g) have bugs with a single UTIME_OMIT,
but work if both times are either explicitly specified or
UTIME_NOW. Work around it with a preparatory [l]stat prior
to calling utimensat; fortunately, there is not much timing
impact due to the extra syscall even on file systems where
UTIME_OMIT would have worked.
The same bug occurs in Solaris 11.1 (Apr 2013).
FIXME: Simplify this in 2024, when these file system bugs are
no longer common on Gnulib target platforms. */
if (times && (times[0].tv_nsec == UTIME_OMIT
|| times[1].tv_nsec == UTIME_OMIT))
{
if (fstatat (fd, file, &st, flag))
return -1;
if (times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT)
return 0;
if (times[0].tv_nsec == UTIME_OMIT)
ts[0] = get_stat_atime (&st);
else
ts[0] = times[0];
if (times[1].tv_nsec == UTIME_OMIT)
ts[1] = get_stat_mtime (&st);
else
ts[1] = times[1];
times = ts;
}
# ifdef __hppa__
/* Linux kernel 2.6.22.19 on hppa does not reject invalid tv_nsec
values. */
else if (times
&& ((times[0].tv_nsec != UTIME_NOW
&& ! (0 <= times[0].tv_nsec
&& times[0].tv_nsec < TIMESPEC_HZ))
|| (times[1].tv_nsec != UTIME_NOW
&& ! (0 <= times[1].tv_nsec
&& times[1].tv_nsec < TIMESPEC_HZ))))
{
errno = EINVAL;
return -1;
}
# endif
# endif
result = utimensat (fd, file, times, flag);
/* Linux kernel 2.6.25 has a bug where it returns EINVAL for
UTIME_NOW or UTIME_OMIT with non-zero tv_sec, which
local_utimensat works around. Meanwhile, EINVAL for a bad
flag is indeterminate whether the native utimensat works, but
local_utimensat will also reject it. */
if (result == -1 && errno == EINVAL && (flag & ~AT_SYMLINK_NOFOLLOW))
return result;
if (result == 0 || (errno != ENOSYS && errno != EINVAL))
{
utimensat_works_really = 1;
return result;
}
}
/* No point in trying openat/futimens, since on Linux, futimens is
implemented with the same syscall as utimensat. Only avoid the
native utimensat due to an ENOSYS failure; an EINVAL error was
data-dependent, and the next caller may pass valid data. */
if (0 <= utimensat_works_really && errno == ENOSYS)
utimensat_works_really = -1;
return local_utimensat (fd, file, times, flag);
}
#else /* !HAVE_UTIMENSAT */
# define AT_FUNC_NAME utimensat
#endif /* !HAVE_UTIMENSAT */
/* Set the access and modification timestamps of FILE to be
TIMESPEC[0] and TIMESPEC[1], respectively; relative to directory
FD. If flag is AT_SYMLINK_NOFOLLOW, change the times of a symlink,
or fail with ENOSYS if not possible. If TIMESPEC is null, set the
timestamps to the current time. If possible, do it without
changing the working directory. Otherwise, resort to using
save_cwd/fchdir, then utimens/restore_cwd. If either the save_cwd
or the restore_cwd fails, then give a diagnostic and exit nonzero.
Return 0 on success, -1 (setting errno) on failure. */
/* AT_FUNC_NAME is now utimensat or local_utimensat. */
#define AT_FUNC_F1 lutimens
#define AT_FUNC_F2 utimens
#define AT_FUNC_USE_F1_COND AT_SYMLINK_NOFOLLOW
#define AT_FUNC_POST_FILE_PARAM_DECLS , struct timespec const ts[2], int flag
#define AT_FUNC_POST_FILE_ARGS , ts
#include "at-func.c"
#undef AT_FUNC_NAME
#undef AT_FUNC_F1
#undef AT_FUNC_F2
#undef AT_FUNC_USE_F1_COND
#undef AT_FUNC_POST_FILE_PARAM_DECLS
#undef AT_FUNC_POST_FILE_ARGS

View file

@ -181,6 +181,7 @@ Optional argument FACE specifies the face to do the highlighting."
(overlay-put o 'original-face (overlay-get o 'face))
;; Make this overlay take priority over the `transient-mark-mode'
;; overlay.
(overlay-put o 'original-priority (overlay-get o 'priority))
(overlay-put o 'priority 1)
(setq pulse-momentary-overlay o)
(if (eq pulse-flag 'never)
@ -214,6 +215,7 @@ Optional argument FACE specifies the face to do the highlighting."
(let ((ol pulse-momentary-overlay))
(overlay-put ol 'face (overlay-get ol 'original-face))
(overlay-put ol 'original-face nil)
(overlay-put ol 'priority (overlay-get ol 'original-priority))
;; Clear the overlay if it needs deleting.
(when (overlay-get ol 'pulse-delete) (delete-overlay ol)))

View file

@ -2171,50 +2171,9 @@ With argument ARG, insert value in current buffer after the form."
;; Make warnings about unresolved functions
;; give the end of the file as their position.
(setq byte-compile-last-position (point-max))
(byte-compile-warn-about-unresolved-functions))
;; Fix up the header at the front of the output
;; if the buffer contains multibyte characters.
(and byte-compile-current-file
(with-current-buffer byte-compile--outbuffer
(byte-compile-fix-header byte-compile-current-file))))
(byte-compile-warn-about-unresolved-functions)))
byte-compile--outbuffer)))
(defun byte-compile-fix-header (_filename)
"If the current buffer has any multibyte characters, insert a version test."
(when (< (point-max) (position-bytes (point-max)))
(goto-char (point-min))
;; Find the comment that describes the version condition.
(when (search-forward "\n;;; This file does not contain utf-8" nil t)
(narrow-to-region (line-beginning-position) (point-max))
;; Find the first line of ballast semicolons.
(search-forward ";;;;;;;;;;")
(beginning-of-line)
(narrow-to-region (point-min) (point))
(let ((old-header-end (point))
(minimum-version "23")
delta)
(delete-region (point-min) (point-max))
(insert
";;; This file contains utf-8 non-ASCII characters,\n"
";;; and so cannot be loaded into Emacs 22 or earlier.\n"
;; Have to check if emacs-version is bound so that this works
;; in files loaded early in loadup.el.
"(and (boundp 'emacs-version)\n"
;; If there is a name at the end of emacs-version,
;; don't try to check the version number.
" (< (aref emacs-version (1- (length emacs-version))) ?A)\n"
(format " (string-lessp emacs-version \"%s\")\n" minimum-version)
;; Because the header must fit in a fixed width, we cannot
;; insert arbitrary-length file names (Bug#11585).
" (error \"`%s' was compiled for "
(format "Emacs %s or later\" #$))\n\n" minimum-version))
;; Now compensate for any change in size, to make sure all
;; positions in the file remain valid.
(setq delta (- (point-max) old-header-end))
(goto-char (point-max))
(widen)
(delete-char delta)))))
(defun byte-compile-insert-header (_filename outbuffer)
"Insert a header at the start of OUTBUFFER.
Call from the source buffer."
@ -2232,7 +2191,19 @@ Call from the source buffer."
;; 0 string ;ELC GNU Emacs Lisp compiled file,
;; >4 byte x version %d
(insert
";ELC" 23 "\000\000\000\n"
";ELC"
(let ((version
(if (zerop emacs-minor-version)
;; Let's allow silently loading into Emacs-27
;; files compiled with Emacs-28.0.NN since the two can
;; be almost identical (e.g. right after cutting the
;; release branch) and people running the development
;; branch can be presumed to know that it's risky anyway.
(1- emacs-major-version) emacs-major-version)))
;; Make sure the version is a plain byte that doesn't end the comment!
(cl-assert (and (> version 13) (< version 128)))
version)
"\000\000\000\n"
";;; Compiled\n"
";;; in Emacs version " emacs-version "\n"
";;; with"
@ -2244,16 +2215,7 @@ Call from the source buffer."
".\n"
(if dynamic ";;; Function definitions are lazy-loaded.\n"
"")
"\n"
;; Note that byte-compile-fix-header may change this.
";;; This file does not contain utf-8 non-ASCII characters,\n"
";;; and so can be loaded in Emacs versions earlier than 23.\n\n"
;; Insert semicolons as ballast, so that byte-compile-fix-header
;; can delete them so as to keep the buffer positions
;; constant for the actual compiled code.
";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n\n"))))
"\n\n"))))
(defun byte-compile-output-file-form (form)
;; Write the given form to the output buffer, being careful of docstrings

View file

@ -168,7 +168,7 @@
;; not specifically docstring related. Would this even be useful?
;;; Code:
(defvar checkdoc-version "0.6.1"
(defvar checkdoc-version "0.6.2"
"Release version of checkdoc you are currently running.")
(require 'cl-lib)
@ -2073,7 +2073,7 @@ If the offending word is in a piece of quoted text, then it is skipped."
;; piece of an abbreviation
;; FIXME etc
(looking-at
"\\([a-zA-Z]\\|[iI]\\.?e\\|[eE]\\.?g\\)\\."))
"\\([a-zA-Z]\\|[iI]\\.?e\\|[eE]\\.?g\\|[cC]f\\)\\."))
(error t))))
(if (checkdoc-autofix-ask-replace
b e

View file

@ -556,11 +556,7 @@ too large if positive or too small if negative)."
(defun cl-concatenate (type &rest sequences)
"Concatenate, into a sequence of type TYPE, the argument SEQUENCEs.
\n(fn TYPE SEQUENCE...)"
(pcase type
('vector (apply #'vconcat sequences))
('string (apply #'concat sequences))
('list (apply #'append (append sequences '(nil))))
(_ (error "Not a sequence type name: %S" type))))
(seq-concatenate type sequences))
;;; List functions.

View file

@ -141,61 +141,63 @@ By convention, this is a list of symbols where each symbol stands for the
;;; Detect cursor movement.
(defun cursor-sensor--detect (&optional window)
(unless cursor-sensor-inhibit
(let* ((point (window-point window))
;; It's often desirable to make the cursor-sensor-functions property
;; non-sticky on both ends, but that means get-pos-property might
;; never see it.
(new (and (eq (current-buffer) (window-buffer))
(or (get-char-property point 'cursor-sensor-functions)
(unless (<= (point-min) point)
(get-char-property (1- point) 'cursor-sensor-functions)))))
(old (window-parameter window 'cursor-sensor--last-state))
(oldposmark (car old))
(oldpos (or (if oldposmark (marker-position oldposmark))
(point-min)))
(start (min oldpos point))
(end (max oldpos point)))
(unless (or (null old) (eq (marker-buffer oldposmark) (current-buffer)))
;; `window' does not display the same buffer any more!
(setcdr old nil))
(if (or (and (null new) (null (cdr old)))
(and (eq new (cdr old))
(eq (next-single-char-property-change
start 'cursor-sensor-functions nil end)
end)))
;; Clearly nothing to do.
nil
;; Maybe something to do. Let's see exactly what needs to run.
(let* ((missing-p
(lambda (f)
"Non-nil if F is missing somewhere between START and END."
(let ((pos start)
(missing nil))
(while (< pos end)
(setq pos (next-single-char-property-change
pos 'cursor-sensor-functions
nil end))
(unless (memq f (get-char-property
pos 'cursor-sensor-functions))
(setq missing t)))
missing)))
(window (selected-window)))
(dolist (f (cdr old))
(unless (and (memq f new) (not (funcall missing-p f)))
(funcall f window oldpos 'left)))
(dolist (f new)
(unless (and (memq f (cdr old)) (not (funcall missing-p f)))
(funcall f window oldpos 'entered)))))
(with-current-buffer (window-buffer window)
(unless cursor-sensor-inhibit
(let* ((point (window-point window))
;; It's often desirable to make the
;; cursor-sensor-functions property non-sticky on both
;; ends, but that means get-pos-property might never
;; see it.
(new (or (get-char-property point 'cursor-sensor-functions)
(unless (<= (point-min) point)
(get-char-property (1- point)
'cursor-sensor-functions))))
(old (window-parameter window 'cursor-sensor--last-state))
(oldposmark (car old))
(oldpos (or (if oldposmark (marker-position oldposmark))
(point-min)))
(start (min oldpos point))
(end (max oldpos point)))
(unless (or (null old) (eq (marker-buffer oldposmark) (current-buffer)))
;; `window' does not display the same buffer any more!
(setcdr old nil))
(if (or (and (null new) (null (cdr old)))
(and (eq new (cdr old))
(eq (next-single-char-property-change
start 'cursor-sensor-functions nil end)
end)))
;; Clearly nothing to do.
nil
;; Maybe something to do. Let's see exactly what needs to run.
(let* ((missing-p
(lambda (f)
"Non-nil if F is missing somewhere between START and END."
(let ((pos start)
(missing nil))
(while (< pos end)
(setq pos (next-single-char-property-change
pos 'cursor-sensor-functions
nil end))
(unless (memq f (get-char-property
pos 'cursor-sensor-functions))
(setq missing t)))
missing)))
(window (selected-window)))
(dolist (f (cdr old))
(unless (and (memq f new) (not (funcall missing-p f)))
(funcall f window oldpos 'left)))
(dolist (f new)
(unless (and (memq f (cdr old)) (not (funcall missing-p f)))
(funcall f window oldpos 'entered)))))
;; Remember current state for next time.
;; Re-read cursor-sensor-functions since the functions may have moved
;; window-point!
(if old
(progn (move-marker (car old) point)
(setcdr old new))
(set-window-parameter window 'cursor-sensor--last-state
(cons (copy-marker point) new))))))
;; Remember current state for next time.
;; Re-read cursor-sensor-functions since the functions may have moved
;; window-point!
(if old
(progn (move-marker (car old) point)
(setcdr old new))
(set-window-parameter window 'cursor-sensor--last-state
(cons (copy-marker point) new)))))))
;;;###autoload
(define-minor-mode cursor-sensor-mode

View file

@ -134,7 +134,7 @@ Each entry is:
(if (cdr def)
(error "Not an `rx' symbol definition: %s" form)
(car def)))))
((consp form)
((and (consp form) (symbolp (car form)))
(let* ((op (car form))
(def (rx--lookup-def op)))
(and def
@ -254,22 +254,39 @@ Left-fold the list L, starting with X, by the binary function F."
(setq l (cdr l)))
x)
(defun rx--normalise-or-arg (form)
"Normalise the `or' argument FORM.
Characters become strings, user-definitions and `eval' forms are expanded,
and `or' forms are normalised recursively."
(cond ((characterp form)
(char-to-string form))
((and (consp form) (memq (car form) '(or |)))
(cons (car form) (mapcar #'rx--normalise-or-arg (cdr form))))
((and (consp form) (eq (car form) 'eval))
(rx--normalise-or-arg (rx--expand-eval (cdr form))))
(t
(let ((expanded (rx--expand-def form)))
(if expanded
(rx--normalise-or-arg expanded)
form)))))
(defun rx--all-string-or-args (body)
"If BODY only consists of strings or such `or' forms, return all the strings.
Otherwise throw `rx--nonstring'."
(mapcan (lambda (form)
(cond ((stringp form) (list form))
((and (consp form) (memq (car form) '(or |)))
(rx--all-string-or-args (cdr form)))
(t (throw 'rx--nonstring nil))))
body))
(defun rx--translate-or (body)
"Translate an or-pattern of zero or more rx items.
Return (REGEXP . PRECEDENCE)."
;; FIXME: Possible improvements:
;;
;; - Turn single characters to strings: (or ?a ?b) -> (or "a" "b"),
;; so that they can be candidates for regexp-opt.
;;
;; - Translate compile-time strings (`eval' forms), again for regexp-opt.
;;
;; - Flatten sub-patterns first: (or (or A B) (or C D)) -> (or A B C D)
;; in order to improve effectiveness of regexp-opt.
;; This would also help composability.
;;
;; - Use associativity to run regexp-opt on contiguous subsets of arguments
;; if not all of them are strings. Example:
;; Then call regexp-opt on runs of string arguments. Example:
;; (or (+ digit) "CHARLIE" "CHAN" (+ blank))
;; -> (or (+ digit) (or "CHARLIE" "CHAN") (+ blank))
;;
@ -279,33 +296,32 @@ Return (REGEXP . PRECEDENCE)."
;; so that (or "@" "%" digit (any "A-Z" space) (syntax word))
;; -> (any "@" "%" digit "A-Z" space word)
;; -> "[A-Z@%[:digit:][:space:][:word:]]"
;;
;; Problem: If a subpattern is carefully written to be
;; optimizable by regexp-opt, how do we prevent the transforms
;; above from destroying that property?
;; Example: (or "a" (or "abc" "abd" "abe"))
(cond
((null body) ; No items: a never-matching regexp.
(rx--empty))
((null (cdr body)) ; Single item.
(rx--translate (car body)))
((rx--every #'stringp body) ; All strings.
(cons (list (regexp-opt body nil))
t))
((rx--every #'rx--charset-p body) ; All charsets.
(rx--translate-union nil body))
(t
(cons (append (car (rx--translate (car body)))
(mapcan (lambda (item)
(cons "\\|" (car (rx--translate item))))
(cdr body)))
nil))))
(let* ((args (mapcar #'rx--normalise-or-arg body))
(all-strings (catch 'rx--nonstring (rx--all-string-or-args args))))
(cond
(all-strings ; Only strings.
(cons (list (regexp-opt all-strings nil))
t))
((rx--every #'rx--charset-p args) ; All charsets.
(rx--translate-union nil args))
(t
(cons (append (car (rx--translate (car args)))
(mapcan (lambda (item)
(cons "\\|" (car (rx--translate item))))
(cdr args)))
nil)))))))
(defun rx--charset-p (form)
"Whether FORM looks like a charset, only consisting of character intervals
and set operations."
(or (and (consp form)
(or (and (memq (car form) '(any 'in 'char))
(or (and (memq (car form) '(any in char))
(rx--every (lambda (x) (not (symbolp x))) (cdr form)))
(and (memq (car form) '(not or | intersection))
(rx--every #'rx--charset-p (cdr form)))))
@ -344,7 +360,7 @@ character X becomes (?X . ?X). Return the intervals in a list."
(push (cons start end) intervals))
(t
(error "Invalid rx `any' range: %s"
(substring str i 3))))
(substring str i (+ i 3)))))
(setq i (+ i 3))))
(t
;; Single character.
@ -450,6 +466,10 @@ classes."
(not negated))
(cons (list (regexp-quote (char-to-string (caar items))))
t))
;; Negated newline.
((and (equal items '((?\n . ?\n)))
negated)
(rx--translate-symbol 'nonl))
;; At least one character or class, possibly negated.
(t
(cons
@ -836,11 +856,15 @@ Return (REGEXP . PRECEDENCE)."
(cons (list (list 'regexp-quote arg)) 'seq))
(t (error "rx `literal' form with non-string argument")))))
(defun rx--translate-eval (body)
"Translate the `eval' form. Return (REGEXP . PRECEDENCE)."
(defun rx--expand-eval (body)
"Expand `eval' arguments. Return a new rx form."
(unless (and body (null (cdr body)))
(error "rx `eval' form takes exactly one argument"))
(rx--translate (eval (car body))))
(eval (car body)))
(defun rx--translate-eval (body)
"Translate the `eval' form. Return (REGEXP . PRECEDENCE)."
(rx--translate (rx--expand-eval body)))
(defvar rx--regexp-atomic-regexp nil)

View file

@ -58,6 +58,10 @@
(eval-when-compile (require 'cl-generic))
;; We used to use some sequence functions from cl-lib, but this
;; dependency was swapped around so that it will be easier to make
;; seq.el preloaded in the future. See also Bug#39761#26.
(defmacro seq-doseq (spec &rest body)
"Loop over a sequence.
Evaluate BODY with VAR bound to each element of SEQUENCE, in turn.
@ -285,7 +289,11 @@ sorted. FUNCTION must be a function of one argument."
TYPE must be one of following symbols: vector, string or list.
\n(fn TYPE SEQUENCE...)"
(apply #'cl-concatenate type (seq-map #'seq-into-sequence sequences)))
(pcase type
('vector (apply #'vconcat sequences))
('string (apply #'concat sequences))
('list (apply #'append (append sequences '(nil))))
(_ (error "Not a sequence type name: %S" type))))
(cl-defgeneric seq-into-sequence (sequence)
"Convert SEQUENCE into a sequence.

View file

@ -378,9 +378,6 @@ This function returns a timer object which you can use in
(decoded-time-year now)
(decoded-time-zone now)))))))
(or (consp time)
(error "Invalid time format"))
(let ((timer (timer-create)))
(timer-set-time timer time repeat)
(timer-set-function timer function args)

View file

@ -75,7 +75,7 @@
(eval-when-compile (require 'subr-x))
(defvar erc-official-location
"https://www.emacswiki.org/emacs/ERC (mailing list: erc-discuss@gnu.org)"
"https://www.emacswiki.org/emacs/ERC (mailing list: emacs-erc@gnu.org)"
"Location of the ERC client on the Internet.")
(defgroup erc nil

View file

@ -5944,9 +5944,10 @@ into NEWNAME instead."
;; Set directory attributes.
(let ((modes (file-modes directory))
(times (and keep-time (file-attribute-modification-time
(file-attributes directory)))))
(if modes (set-file-modes newname modes (unless follow 'nofollow)))
(if times (set-file-times newname times))))))
(file-attributes directory))))
(follow-flag (unless follow 'nofollow)))
(if modes (set-file-modes newname modes follow-flag))
(if times (set-file-times newname times follow-flag))))))
;; At time of writing, only info uses this.

View file

@ -713,6 +713,18 @@ The optional argument PARAMETERS specifies additional frame parameters."
(x-display-list))))
(make-frame (cons (cons 'display display) parameters)))
(defun make-frame-on-current-monitor (&optional parameters)
"Make a frame on the currently selected monitor.
Like `make-frame-on-monitor' and with the same PARAMETERS as in `make-frame'."
(interactive)
(let* ((monitor-workarea
(cdr (assq 'workarea (frame-monitor-attributes))))
(geometry-parameters
(when monitor-workarea
`((top . ,(nth 1 monitor-workarea))
(left . ,(nth 0 monitor-workarea))))))
(make-frame (append geometry-parameters parameters))))
(defun make-frame-on-monitor (monitor &optional display parameters)
"Make a frame on monitor MONITOR.
The optional argument DISPLAY can be a display name, and the optional

View file

@ -7774,11 +7774,11 @@ also be Lisp expression evaluating to a string),
BUTTON: is the number of the regexp grouping actually matching the button,
FORM: is a Lisp expression which must eval to true for the button to
be added,
CALLBACK: is the function to call when the user push this button, and each
CALLBACK: is the function to call when the user pushes this button, and each
PAR: is a number of a regexp grouping whose text will be passed to CALLBACK.
CALLBACK can also be a variable, in that case the value of that
variable it the real callback function."
CALLBACK can also be a variable, in which case the value of that
variable is the real callback function."
:group 'gnus-article-buttons
:type '(repeat (list (choice regexp variable sexp)
(integer :tag "Button")

View file

@ -285,8 +285,8 @@ Use old data if FORCE-OLDER is not nil."
(insert new-contents)
(when (file-exists-p file-name)
(rename-file file-name (car (find-backup-file-name file-name))))
(write-region (point-min) (point-max) file-name)
(set-file-times file-name (parse-iso8601-time-string date))))
(write-region (point-min) (point-max) file-name nil nil nil 'excl)
(set-file-times file-name (parse-iso8601-time-string date) 'nofollow)))
(defun gnus-cloud-file-covered-p (file-name)
(let ((matched nil))

View file

@ -174,7 +174,7 @@ no effect when spam-stat is invoked through spam.el."
(defcustom spam-stat-score-buffer-user-functions nil
"List of additional scoring functions.
Called one by one on the buffer.
Called one by one on the buffer.
If all of these functions return non-nil answers, these numerical
answers are added to the computed spam stat score on the buffer. If

View file

@ -953,7 +953,7 @@ it is displayed along with the global value."
(unless (buffer-live-p buffer) (setq buffer (current-buffer)))
(unless (frame-live-p frame) (setq frame (selected-frame)))
(if (not (symbolp variable))
(message "You did not specify a variable")
(user-error "You didn't specify a variable")
(save-excursion
(let ((valvoid (not (with-current-buffer buffer (boundp variable))))
val val-start-pos locus)
@ -1009,6 +1009,8 @@ it is displayed along with the global value."
(terpri)
(let ((buf (current-buffer)))
(with-temp-buffer
(lisp-mode-variables nil)
(set-syntax-table emacs-lisp-mode-syntax-table)
(insert print-rep)
(pp-buffer)
(let ((pp-buffer (current-buffer)))
@ -1442,7 +1444,7 @@ current buffer and the selected frame, respectively."
t nil nil
(if found (symbol-name v-or-f)))))
(list (if (equal val "")
v-or-f (intern val)))))
(or v-or-f "") (intern val)))))
(if (not (symbolp symbol))
(user-error "You didn't specify a function or variable"))
(unless (buffer-live-p buffer) (setq buffer (current-buffer)))

View file

@ -284,6 +284,17 @@ require user confirmation."
(t
(icomplete-force-complete-and-exit)))))
(defun icomplete-fido-exit (force)
"Attempt to exit minibuffer immediately with current input.
Unless FORCE is non-nil (interactively with a prefix argument),
honour a non-nil REQUIRE-MATCH argument to `completing-read' by
trying to complete as much as possible and disallowing the exit
if that doesn't produce a completion match."
(interactive "P")
(if (and (not force) minibuffer--require-match)
(minibuffer-complete-and-exit)
(exit-minibuffer)))
(defun icomplete-fido-backward-updir ()
"Delete char before or go up directory, like `ido-mode'."
(interactive)
@ -299,7 +310,7 @@ require user confirmation."
(define-key map (kbd "RET") 'icomplete-fido-ret)
(define-key map (kbd "C-m") 'icomplete-fido-ret)
(define-key map (kbd "DEL") 'icomplete-fido-backward-updir)
(define-key map (kbd "M-j") 'exit-minibuffer)
(define-key map (kbd "M-j") 'icomplete-fido-exit)
(define-key map (kbd "C-s") 'icomplete-forward-completions)
(define-key map (kbd "C-r") 'icomplete-backward-completions)
(define-key map (kbd "<right>") 'icomplete-forward-completions)
@ -541,7 +552,7 @@ See `icomplete-mode' and `minibuffer-setup-hook'."
(icomplete--completion-table)
(icomplete--completion-predicate)
(if (window-minibuffer-p)
(not minibuffer-completion-confirm)))))
(eq minibuffer--require-match t)))))
(buffer-undo-list t)
deactivate-mark)
;; Do nothing if while-no-input was aborted.

View file

@ -2601,7 +2601,7 @@ This function is intended to be added to `auto-coding-functions'."
(detect-coding-region (point-min) size t)))))
;; Pure ASCII always comes back as undecided.
(if (memq detected
'(utf-8 'utf-8-with-signature 'utf-8-hfs undecided))
'(utf-8 utf-8-with-signature utf-8-hfs undecided))
'utf-8
(warn "File contents detected as %s.
Consider adding an encoding attribute to the xml declaration,

View file

@ -173,7 +173,7 @@ documentation of `unload-feature' for details.")
;; we undefine it.
;; So we use this auxiliary variable to keep track of the last (t . SYMBOL)
;; that occurred.
(defvar loadhist--restore-autoload
(defvar loadhist--restore-autoload nil
"If non-nil, this is a symbol for which we should
restore a previous autoload if possible.")

View file

@ -1400,7 +1400,11 @@ scroll the window of possible completions."
(minibuffer-prompt-end) (point-max) #'exit-minibuffer
;; If the previous completion completed to an element which fails
;; test-completion, then we shouldn't exit, but that should be rare.
(lambda () (minibuffer-message "Incomplete"))))
(lambda ()
(if minibuffer--require-match
(minibuffer-message "Incomplete")
;; If a match is not required, exit after all.
(exit-minibuffer)))))
(defun minibuffer-force-complete (&optional start end dont-cycle)
"Complete the minibuffer to an exact match.
@ -1464,6 +1468,9 @@ DONT-CYCLE tells the function not to setup cycling."
"List of commands which cause an immediately following
`minibuffer-complete-and-exit' to ask for extra confirmation.")
(defvar minibuffer--require-match nil
"Value of REQUIRE-MATCH passed to `completing-read'.")
(defun minibuffer-complete-and-exit ()
"Exit if the minibuffer contains a valid completion.
Otherwise, try to complete the minibuffer contents. If
@ -3748,8 +3755,10 @@ See `completing-read' for the meaning of the arguments."
(let* ((minibuffer-completion-table collection)
(minibuffer-completion-predicate predicate)
;; FIXME: Remove/rename this var, see the next one.
(minibuffer-completion-confirm (unless (eq require-match t)
require-match))
(minibuffer--require-match require-match)
(base-keymap (if require-match
minibuffer-local-must-match-map
minibuffer-local-completion-map))

View file

@ -674,8 +674,9 @@ But handle the case, if the \"test\" command is not available."
(tramp-adb-send-command-and-check
v (format "chmod %o %s" mode localname)))))
(defun tramp-adb-handle-set-file-times (filename &optional time)
(defun tramp-adb-handle-set-file-times (filename &optional time flag)
"Like `set-file-times' for Tramp files."
flag ;; FIXME: Support 'nofollow'.
(with-parsed-tramp-file-name filename nil
(tramp-flush-file-properties v localname)
(let ((time (if (or (null time)
@ -777,7 +778,8 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(set-file-times
newname
(tramp-compat-file-attribute-modification-time
(file-attributes filename))))))
(file-attributes filename))
(unless ok-if-already-exists 'nofollow)))))
(defun tramp-adb-handle-rename-file
(filename newname &optional ok-if-already-exists)

View file

@ -1571,7 +1571,7 @@ If FILE-SYSTEM is non-nil, return file system attributes."
(tramp-gvfs-url-file-name (tramp-make-tramp-file-name v))
"unix::mode" (number-to-string mode))))
(defun tramp-gvfs-handle-set-file-times (filename &optional time)
(defun tramp-gvfs-handle-set-file-times (filename &optional time flag)
"Like `set-file-times' for Tramp files."
(with-parsed-tramp-file-name filename nil
(tramp-flush-file-properties v localname)
@ -1582,7 +1582,7 @@ If FILE-SYSTEM is non-nil, return file system attributes."
(current-time)
time)))
(tramp-gvfs-send-command
v "gvfs-set-attribute" "-t" "uint64"
v "gvfs-set-attribute" (if flag "-nt" "-t") "uint64"
(tramp-gvfs-url-file-name (tramp-make-tramp-file-name v))
"time::modified" (format-time-string "%s" time)))))

View file

@ -1495,11 +1495,12 @@ of."
mode (tramp-shell-quote-argument localname))
"Error while changing file's mode %s" filename))))
(defun tramp-sh-handle-set-file-times (filename &optional time)
(defun tramp-sh-handle-set-file-times (filename &optional time flag)
"Like `set-file-times' for Tramp files."
(with-parsed-tramp-file-name filename nil
(when (tramp-get-remote-touch v)
(tramp-flush-file-properties v localname)
flag ;; FIXME: Support 'nofollow'.
(let ((time
(if (or (null time)
(tramp-compat-time-equal-p time tramp-time-doesnt-exist)

View file

@ -619,7 +619,8 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(set-file-times
newname
(tramp-compat-file-attribute-modification-time
(file-attributes filename))))))
(file-attributes filename))
(unless ok-if-already-exists 'nofollow)))))
(defun tramp-smb-handle-delete-directory (directory &optional recursive _trash)
"Like `delete-directory' for Tramp files."

View file

@ -523,10 +523,11 @@ the result will be a local, non-Tramp, file name."
(string-to-number (match-string 2)))
(string-to-number (match-string 3)))))))))
(defun tramp-sudoedit-handle-set-file-times (filename &optional time)
(defun tramp-sudoedit-handle-set-file-times (filename &optional time flag)
"Like `set-file-times' for Tramp files."
(with-parsed-tramp-file-name filename nil
(tramp-flush-file-properties v localname)
flag ;; FIXME: Support 'nofollow'.
(let ((time
(if (or (null time)
(tramp-compat-time-equal-p time tramp-time-doesnt-exist)

View file

@ -48,6 +48,7 @@
(cc-bytecomp-defvar filladapt-mode) ; c-fill-paragraph contains a kludge
; which looks at this.
(cc-bytecomp-defun electric-pair-post-self-insert-function)
(cc-bytecomp-defvar c-indent-to-body-directives)
;; Indentation / Display syntax functions
(defvar c-fix-backslashes t)
@ -1441,6 +1442,98 @@ keyword on the line, the keyword is not inserted inside a literal, and
(indent-according-to-mode)
(delete-char -2)))))
(defun c-align-cpp-indent-to-body ()
"Align a \"#pragma\" line under the previous line.
This function is intented for use as a member of `c-special-indent-hook'."
(when (assq 'cpp-macro c-syntactic-context)
(when
(save-excursion
(save-match-data
(back-to-indentation)
(and
(looking-at (concat c-opt-cpp-symbol "[ \t]*\\([a-zA-Z0-9_]+\\)"))
(member (match-string-no-properties 1)
c-cpp-indent-to-body-directives))))
(c-indent-line (delete '(cpp-macro) c-syntactic-context)))))
(defvar c-cpp-indent-to-body-flag nil)
;; Non-nil when CPP directives such as "#pragma" should be indented to under
;; the preceding statement.
(make-variable-buffer-local 'c-cpp-indent-to-body-flag)
(defun c-electric-pragma ()
"Reindent the current line if appropriate.
This function is used to reindent a preprocessor line when the
symbol for the directive, typically \"pragma\", triggers this
function as a hook function of an abbreviation.
The \"#\" of the preprocessor construct is aligned under the
first anchor point of the line's syntactic context.
The line is reindented if the construct is not in a string or
comment, there is exactly one \"#\" contained in optional
whitespace before it on the current line, and `c-electric-flag'
and `c-syntactic-indentation' are both non-nil."
(save-excursion
(save-match-data
(when
(and
c-cpp-indent-to-body-flag
c-electric-flag
c-syntactic-indentation
last-abbrev-location
c-opt-cpp-symbol ; "#" or nil.
(progn (back-to-indentation)
(looking-at (concat c-opt-cpp-symbol "[ \t]*")))
(>= (match-end 0) last-abbrev-location)
(not (c-literal-limits)))
(c-indent-line (delete '(cpp-macro) (c-guess-basic-syntax)))))))
(defun c-add-indent-to-body-to-abbrev-table (d)
;; Create an abbreviation table entry for the directive D, and add it to the
;; current abbreviation table. Existing abbreviation (e.g. for "else") do
;; not get overwritten.
(when (and c-buffer-is-cc-mode
local-abbrev-table
(not (abbrev-symbol d local-abbrev-table)))
(condition-case nil
(define-abbrev local-abbrev-table d d 'c-electric-pragma 0 t)
(wrong-number-of-arguments
(define-abbrev local-abbrev-table d d 'c-electric-pragma)))))
(defun c-clear-stale-indent-to-body-abbrevs ()
;; Fill in this comment. FIXME!!!
(when (fboundp 'abbrev-get)
(mapatoms (lambda (a)
(when (and (abbrev-get a ':system) ; Preserve a user's abbrev!
(not (member (symbol-name a) c-std-abbrev-keywords))
(not (member (symbol-name a)
c-cpp-indent-to-body-directives)))
(unintern a local-abbrev-table)))
local-abbrev-table)))
(defun c-toggle-cpp-indent-to-body (&optional arg)
"Toggle the C preprocessor indent-to-body feature.
When enabled, preprocessor directives which are words in
`c-indent-to-body-directives' are indented as if they were statements.
Optional numeric ARG, if supplied, turns on the feature when positive,
turns it off when negative, and just toggles it when zero or
left out."
(interactive "P")
(setq c-cpp-indent-to-body-flag
(c-calculate-state arg c-cpp-indent-to-body-flag))
(if c-cpp-indent-to-body-flag
(progn
(c-clear-stale-indent-to-body-abbrevs)
(mapc 'c-add-indent-to-body-to-abbrev-table
c-cpp-indent-to-body-directives)
(add-hook 'c-special-indent-hook 'c-align-cpp-indent-to-body nil t))
(remove-hook 'c-special-indent-hook 'c-align-cpp-indent-to-body t))
(message "c-cpp-indent-to-body %sabled"
(if c-cpp-indent-to-body-flag "en" "dis")))
(declare-function subword-forward "subword" (&optional arg))

View file

@ -3030,7 +3030,14 @@ Note that Java specific rules are currently applied to tell this from
;; can start a declaration.)
"entity" "process" "service" "session" "storage"))
(c-lang-defconst c-std-abbrev-keywords
"List of keywords which may need to cause electric indentation."
t '("else" "while")
c++ (append (c-lang-const c-std-abbrev-keywords) '("catch"))
java (append (c-lang-const c-std-abbrev-keywords) '("catch" "finally"))
idl nil)
(c-lang-defvar c-std-abbrev-keywords (c-lang-const c-std-abbrev-keywords))
;;; Constants built from keywords.
;; Note: No `*-kwds' language constants may be defined below this point.

View file

@ -278,6 +278,29 @@ control). See \"cc-mode.el\" for more info."
(setq defs (cdr defs)))))
(put 'c-define-abbrev-table 'lisp-indent-function 1)
(defun c-populate-abbrev-table ()
;; Insert the standard keywords which may need electric indentation into the
;; current mode's abbreviation table.
(let ((table (intern (concat (symbol-name major-mode) "-abbrev-table")))
(defs c-std-abbrev-keywords)
)
(unless (and (boundp table)
(abbrev-table-p (symbol-value table)))
(define-abbrev-table table nil))
(setq local-abbrev-table (symbol-value table))
(while defs
(unless (intern-soft (car defs) local-abbrev-table) ; Don't overwrite the
; abbrev's use count.
(condition-case nil
(define-abbrev (symbol-value table)
(car defs) (car defs)
'c-electric-continued-statement 0 t)
(wrong-number-of-arguments
(define-abbrev (symbol-value table)
(car defs) (car defs)
'c-electric-continued-statement 0))))
(setq defs (cdr defs)))))
(defun c-bind-special-erase-keys ()
;; Only used in Emacs to bind C-c C-<delete> and C-c C-<backspace>
;; to the proper keys depending on `normal-erase-is-backspace'.
@ -550,6 +573,8 @@ that requires a literal mode spec at compile time."
(setq c-buffer-is-cc-mode mode)
(c-populate-abbrev-table)
;; these variables should always be buffer local; they do not affect
;; indentation style.
(make-local-variable 'comment-start)
@ -1865,18 +1890,25 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
;; it/them from the cache. Don't worry about being inside a string
;; or a comment - "wrongly" removing a symbol from `c-found-types'
;; isn't critical.
(unless (or (c-called-from-text-property-change-p)
c-just-done-before-change) ; guard against a spurious second
; invocation of before-change-functions.
(setq c-just-done-before-change t)
;; (c-new-BEG c-new-END) will be the region to fontify.
(setq c-new-BEG beg c-new-END end)
(setq c-maybe-stale-found-type nil)
;; A workaround for syntax-ppss's failure to notice syntax-table text
;; property changes.
(when (fboundp 'syntax-ppss)
(setq c-syntax-table-hwm most-positive-fixnum))
(unless (c-called-from-text-property-change-p)
(save-restriction
(widen)
(if c-just-done-before-change
;; We have two consecutive calls to `before-change-functions' without
;; an intervening `after-change-functions'. An example of this is bug
;; #38691. To protect CC Mode, assume that the entire buffer has
;; changed.
(setq beg (point-min)
end (point-max)
c-just-done-before-change 'whole-buffer)
(setq c-just-done-before-change t))
;; (c-new-BEG c-new-END) will be the region to fontify.
(setq c-new-BEG beg c-new-END end)
(setq c-maybe-stale-found-type nil)
;; A workaround for syntax-ppss's failure to notice syntax-table text
;; property changes.
(when (fboundp 'syntax-ppss)
(setq c-syntax-table-hwm most-positive-fixnum))
(save-match-data
(widen)
(unwind-protect
@ -1982,14 +2014,19 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
;; without an intervening call to `before-change-functions' when reverting
;; the buffer (see bug #24094). Whatever the cause, assume that the entire
;; buffer has changed.
(when (and (not c-just-done-before-change)
(not (c-called-from-text-property-change-p)))
(save-restriction
(widen)
(c-before-change (point-min) (point-max))
(setq beg (point-min)
end (point-max)
old-len (- end beg))))
;; Note: c-just-done-before-change is nil, t, or 'whole-buffer.
(unless (c-called-from-text-property-change-p)
(unless (eq c-just-done-before-change t)
(save-restriction
(widen)
(when (null c-just-done-before-change)
(c-before-change (point-min) (point-max)))
(setq beg (point-min)
end (point-max)
old-len (- end beg)
c-new-BEG (point-min)
c-new-END (point-max)))))
;; (c-new-BEG c-new-END) will be the region to fontify. It may become
;; larger than (beg end).
@ -2432,11 +2469,6 @@ opening \" and the next unescaped end of line."
(funcall (c-lang-const c-make-mode-syntax-table c))
"Syntax table used in c-mode buffers.")
(c-define-abbrev-table 'c-mode-abbrev-table
'(("else" "else" c-electric-continued-statement 0)
("while" "while" c-electric-continued-statement 0))
"Abbreviation table used in c-mode buffers.")
(defvar c-mode-map
(let ((map (c-make-inherited-keymap)))
map)
@ -2548,12 +2580,6 @@ the code is C or C++ and based on that chooses whether to enable
(funcall (c-lang-const c-make-mode-syntax-table c++))
"Syntax table used in c++-mode buffers.")
(c-define-abbrev-table 'c++-mode-abbrev-table
'(("else" "else" c-electric-continued-statement 0)
("while" "while" c-electric-continued-statement 0)
("catch" "catch" c-electric-continued-statement 0))
"Abbreviation table used in c++-mode buffers.")
(defvar c++-mode-map
(let ((map (c-make-inherited-keymap)))
map)
@ -2602,11 +2628,6 @@ Key bindings:
(funcall (c-lang-const c-make-mode-syntax-table objc))
"Syntax table used in objc-mode buffers.")
(c-define-abbrev-table 'objc-mode-abbrev-table
'(("else" "else" c-electric-continued-statement 0)
("while" "while" c-electric-continued-statement 0))
"Abbreviation table used in objc-mode buffers.")
(defvar objc-mode-map
(let ((map (c-make-inherited-keymap)))
map)
@ -2653,13 +2674,6 @@ Key bindings:
(funcall (c-lang-const c-make-mode-syntax-table java))
"Syntax table used in java-mode buffers.")
(c-define-abbrev-table 'java-mode-abbrev-table
'(("else" "else" c-electric-continued-statement 0)
("while" "while" c-electric-continued-statement 0)
("catch" "catch" c-electric-continued-statement 0)
("finally" "finally" c-electric-continued-statement 0))
"Abbreviation table used in java-mode buffers.")
(defvar java-mode-map
(let ((map (c-make-inherited-keymap)))
map)
@ -2710,9 +2724,6 @@ Key bindings:
(funcall (c-lang-const c-make-mode-syntax-table idl))
"Syntax table used in idl-mode buffers.")
(c-define-abbrev-table 'idl-mode-abbrev-table nil
"Abbreviation table used in idl-mode buffers.")
(defvar idl-mode-map
(let ((map (c-make-inherited-keymap)))
map)
@ -2755,11 +2766,6 @@ Key bindings:
(funcall (c-lang-const c-make-mode-syntax-table pike))
"Syntax table used in pike-mode buffers.")
(c-define-abbrev-table 'pike-mode-abbrev-table
'(("else" "else" c-electric-continued-statement 0)
("while" "while" c-electric-continued-statement 0))
"Abbreviation table used in pike-mode buffers.")
(defvar pike-mode-map
(let ((map (c-make-inherited-keymap)))
map)
@ -2807,11 +2813,6 @@ Key bindings:
;;;###autoload (add-to-list 'interpreter-mode-alist '("nawk" . awk-mode))
;;;###autoload (add-to-list 'interpreter-mode-alist '("gawk" . awk-mode))
(c-define-abbrev-table 'awk-mode-abbrev-table
'(("else" "else" c-electric-continued-statement 0)
("while" "while" c-electric-continued-statement 0))
"Abbreviation table used in awk-mode buffers.")
(defvar awk-mode-map
(let ((map (c-make-inherited-keymap)))
map)

View file

@ -1649,6 +1649,15 @@ white space either before or after the operator, but not both."
:type 'boolean
:group 'c)
(defcustom c-cpp-indent-to-body-directives '("pragma")
"Preprocessor directives which will be indented as statements.
A list of Preprocessor directives which when reindented, or newly
typed in, will cause the \"#\" introducing the directive to be
indented as a statement."
:type '(repeat string)
:group 'c)
;; Initialize the next two to a regexp which never matches.
(defvar c-noise-macro-with-parens-name-re regexp-unmatchable)
(make-variable-buffer-local 'c-noise-macro-with-parens-name-re)

View file

@ -13334,7 +13334,7 @@ File statistics: \"%s\"\n\
(defvar vhdl-font-lock-keywords nil
"Regular expressions to highlight in VHDL Mode.")
(defvar vhdl-font-lock-keywords-0
(defvar vhdl-font-lock-keywords-0 nil
;; set in `vhdl-font-lock-init' because dependent on user options
"For consideration as a value of `vhdl-font-lock-keywords'.
This does highlighting of template prompts and directives (pragmas).")

View file

@ -75,14 +75,16 @@ value of 1 means that nothing is amalgamated.")
:version "22.1")
(defcustom next-error-highlight 0.5
"Highlighting of locations in selected source buffers.
"Highlighting of locations in the selected buffer.
If a number, highlight the locus in `next-error' face for the given time
in seconds, or until the next command is executed.
If t, highlight the locus until the next command is executed, or until
some other locus replaces it.
If nil, don't highlight the locus in the source buffer.
If `fringe-arrow', indicate the locus by the fringe arrow
indefinitely until some other locus replaces it."
indefinitely until some other locus replaces it.
See `next-error-highlight-no-select' to customize highlighting
of the locus in non-selected buffers."
:type '(choice (number :tag "Highlight for specified time")
(const :tag "Semipermanent highlighting" t)
(const :tag "No highlighting" nil)
@ -91,12 +93,15 @@ indefinitely until some other locus replaces it."
:version "22.1")
(defcustom next-error-highlight-no-select 0.5
"Highlighting of locations in `next-error-no-select'.
"Highlighting of locations in non-selected source buffers.
Usually non-selected buffers are displayed by `next-error-no-select'.
If number, highlight the locus in `next-error' face for given time in seconds.
If t, highlight the locus indefinitely until some other locus replaces it.
If nil, don't highlight the locus in the source buffer.
If `fringe-arrow', indicate the locus by the fringe arrow
indefinitely until some other locus replaces it."
indefinitely until some other locus replaces it.
See `next-error-highlight' to customize highlighting of the locus
in the selected buffer."
:type '(choice (number :tag "Highlight for specified time")
(const :tag "Semipermanent highlighting" t)
(const :tag "No highlighting" nil)

View file

@ -3967,19 +3967,18 @@ the function `undo--wrap-and-run-primitive-undo'."
(let ((undo--combining-change-calls t))
(if (not inhibit-modification-hooks)
(run-hook-with-args 'before-change-functions beg end))
(if (eq buffer-undo-list t)
(setq result (funcall body))
(let (;; (inhibit-modification-hooks t)
(before-change-functions
;; Ugly Hack: if the body uses syntax-ppss/syntax-propertize
;; (e.g. via a regexp-search or sexp-movement trigerring
;; on-the-fly syntax-propertize), make sure that this gets
;; properly refreshed after subsequent changes.
(if (memq #'syntax-ppss-flush-cache before-change-functions)
'(syntax-ppss-flush-cache)))
after-change-functions)
(setq result (funcall body)))
(let ((ap-elt
(let (;; (inhibit-modification-hooks t)
(before-change-functions
;; Ugly Hack: if the body uses syntax-ppss/syntax-propertize
;; (e.g. via a regexp-search or sexp-movement trigerring
;; on-the-fly syntax-propertize), make sure that this gets
;; properly refreshed after subsequent changes.
(if (memq #'syntax-ppss-flush-cache before-change-functions)
'(syntax-ppss-flush-cache)))
after-change-functions)
(setq result (funcall body)))
(when (not (eq buffer-undo-list t))
(let ((ap-elt
(list 'apply
(- end end-marker)
beg

View file

@ -446,17 +446,19 @@ variable `tab-line-tabs-function'."
(setq hscroll nil)
(set-window-parameter nil 'tab-line-hscroll hscroll))
(list separator
(when (and (integerp hscroll) (not (zerop hscroll)))
(when (and (numberp hscroll) (not (zerop hscroll)))
tab-line-left-button)
(when (if (integerp hscroll)
(< (abs hscroll) (1- (length strings)))
(when (if (numberp hscroll)
(< (truncate hscroll) (1- (length strings)))
(> (length strings) 1))
tab-line-right-button)))
(if hscroll (nthcdr (abs hscroll) strings) strings)
(if hscroll (nthcdr (truncate hscroll) strings) strings)
(when (eq tab-line-tabs-function #'tab-line-tabs-window-buffers)
(list (concat separator (when tab-line-new-tab-choice
tab-line-new-button)))))))
(defvar tab-line-auto-hscroll)
(defun tab-line-format ()
"Template for displaying tab line for selected window."
(let* ((tabs (funcall tab-line-tabs-function))
@ -464,6 +466,13 @@ variable `tab-line-tabs-function'."
(window-buffer)
(window-parameter nil 'tab-line-hscroll)))
(cache (window-parameter nil 'tab-line-cache)))
;; Enable auto-hscroll again after it was disabled on manual scrolling.
;; The moment to enable it is when the window-buffer was updated.
(when (and tab-line-auto-hscroll ; if auto-hscroll was enabled
(integerp (nth 2 cache-key)) ; integer on manual scroll
cache ; window-buffer was updated
(not (equal (nth 1 (car cache)) (nth 1 cache-key))))
(set-window-parameter nil 'tab-line-hscroll (float (nth 2 cache-key))))
(or (and cache (equal (car cache) cache-key) (cdr cache))
(cdr (set-window-parameter
nil 'tab-line-cache
@ -478,24 +487,27 @@ the selected tab visible."
:group 'tab-line
:version "27.1")
(defvar tab-line-auto-hscroll-buffer (generate-new-buffer " *tab-line-hscroll*"))
(defun tab-line-auto-hscroll (strings hscroll)
(with-temp-buffer
(with-current-buffer tab-line-auto-hscroll-buffer
(let ((truncate-partial-width-windows nil)
(inhibit-modification-hooks t)
show-arrows)
(setq truncate-lines nil)
(erase-buffer)
(apply 'insert strings)
(goto-char (point-min))
(add-face-text-property (point-min) (point-max) 'tab-line)
;; Continuation means tab-line doesn't fit completely,
;; thus scroll arrows are needed for scrolling.
(setq show-arrows (> (vertical-motion 1) 0))
;; Try to auto-scroll only when scrolling is needed,
;; Try to auto-hscroll only when scrolling is needed,
;; but no manual scrolling was performed before.
(when (and tab-line-auto-hscroll
show-arrows
;; Do nothing when scrolled manually
(not (and (integerp hscroll) (>= hscroll 0))))
(not (integerp hscroll)))
(let ((selected (seq-position strings 'selected
(lambda (str prop)
(get-pos-property 1 prop str)))))
@ -503,7 +515,7 @@ the selected tab visible."
((null selected)
;; Do nothing if no tab is selected
)
((or (not (integerp hscroll)) (< selected (abs hscroll)))
((or (not (numberp hscroll)) (< selected (truncate hscroll)))
;; Selected is scrolled to the left, or no scrolling yet
(erase-buffer)
(apply 'insert (reverse (seq-subseq strings 0 (1+ selected))))
@ -520,14 +532,14 @@ the selected tab visible."
(lambda (str tab)
(eq (get-pos-property 1 'tab str) tab))))))
(when new-hscroll
(setq hscroll (- new-hscroll))
(setq hscroll (float new-hscroll))
(set-window-parameter nil 'tab-line-hscroll hscroll)))
(setq hscroll nil)
(set-window-parameter nil 'tab-line-hscroll hscroll)))
(t
;; Check if the selected tab is already visible
(erase-buffer)
(apply 'insert (seq-subseq strings (abs hscroll) (1+ selected)))
(apply 'insert (seq-subseq strings (truncate hscroll) (1+ selected)))
(goto-char (point-min))
(add-face-text-property (point-min) (point-max) 'tab-line)
(when (> (vertical-motion 1) 0)
@ -547,7 +559,7 @@ the selected tab visible."
(lambda (str tab)
(eq (get-pos-property 1 'tab str) tab))))))
(when new-hscroll
(setq hscroll (- new-hscroll))
(setq hscroll (float new-hscroll))
(set-window-parameter nil 'tab-line-hscroll hscroll)))))))))
(list show-arrows hscroll))))
@ -559,7 +571,7 @@ the selected tab visible."
(funcall tab-line-tabs-function))))
(set-window-parameter
window 'tab-line-hscroll
(max 0 (min (+ (if (integerp hscroll) (abs hscroll) 0) (or arg 1))
(max 0 (min (+ (if (numberp hscroll) (truncate hscroll) 0) (or arg 1))
(1- (length tabs)))))
(when window
(force-mode-line-update t))))

View file

@ -1056,7 +1056,7 @@ extracted file."
(write-region start end to-file nil nil nil t))
(when (and tar-copy-preserve-time
date)
(set-file-times to-file date)))
(set-file-times to-file date 'nofollow)))
(message "Copied tar entry %s to %s" name to-file)))
(defun tar-new-entry (filename &optional index)

View file

@ -26,6 +26,16 @@
(require 'term/xterm)
(defgroup rxvt nil
"(U)RXVT support."
:version "28.1"
:group 'terminals)
(defcustom rxvt-set-window-title nil
"Whether Emacs should set window titles to an Emacs frame in RXVT."
:version "28.1"
:type 'boolean)
(defvar rxvt-function-map
(let ((map (make-sparse-keymap)))
(set-keymap-parent map xterm-rxvt-function-map)
@ -171,7 +181,16 @@
(xterm-register-default-colors rxvt-standard-colors)
(rxvt-set-background-mode)
;; This recomputes all the default faces given the colors we've just set up.
(tty-set-up-initial-frame-faces))
(tty-set-up-initial-frame-faces)
;; Unconditionally enable bracketed paste mode: terminals that don't
;; support it just ignore the sequence.
(xterm--init-bracketed-paste-mode)
(when rxvt-set-window-title
(xterm--init-frame-title))
(run-hooks 'terminal-init-rxvt-hook))
;; rxvt puts the default colors into an environment variable
;; COLORFGBG. We use this to set the background mode in a more

View file

@ -1006,32 +1006,36 @@ See `bibtex-generate-autokey' for details."
:type 'boolean)
(defvar bibtex-autokey-transcriptions
'(;; language specific characters
("\\\\aa" . "a") ; \aa -> a
("\\\\AA" . "A") ; \AA -> A
("\\\"a\\|\\\\\\\"a\\|\\\\ae" . "ae") ; "a,\"a,\ae -> ae
("\\\"A\\|\\\\\\\"A\\|\\\\AE" . "Ae") ; "A,\"A,\AE -> Ae
("\\\\i" . "i") ; \i -> i
("\\\\j" . "j") ; \j -> j
("\\\\l" . "l") ; \l -> l
("\\\\L" . "L") ; \L -> L
("\\\"o\\|\\\\\\\"o\\|\\\\o\\|\\\\oe" . "oe") ; "o,\"o,\o,\oe -> oe
("\\\"O\\|\\\\\\\"O\\|\\\\O\\|\\\\OE" . "Oe") ; "O,\"O,\O,\OE -> Oe
("\\\"s\\|\\\\\\\"s\\|\\\\3" . "ss") ; "s,\"s,\3 -> ss
("\\\"u\\|\\\\\\\"u" . "ue") ; "u,\"u -> ue
("\\\"U\\|\\\\\\\"U" . "Ue") ; "U,\"U -> Ue
;; accents
("\\\\`\\|\\\\'\\|\\\\\\^\\|\\\\~\\|\\\\=\\|\\\\\\.\\|\\\\u\\|\\\\v\\|\\\\H\\|\\\\t\\|\\\\c\\|\\\\d\\|\\\\b" . "")
;; braces, quotes, concatenation.
("[`'\"{}#]" . "")
("\\\\-" . "") ; \- ->
;; spaces
("\\\\?[ \t\n]+\\|~" . " "))
(nconc
(mapcar (lambda (a) (cons (regexp-opt (car a)) (cdr a)))
'(;; language specific characters
(("\\aa") . "a") ; \aa -> a
(("\\AA") . "A") ; \AA -> A
(("\"a" "\\\"a" "\\ae") . "ae") ; "a,\"a,\ae -> ae
(("\"A" "\\\"A" "\\AE") . "Ae") ; "A,\"A,\AE -> Ae
(("\\i") . "i") ; \i -> i
(("\\j") . "j") ; \j -> j
(("\\l") . "l") ; \l -> l
(("\\L") . "L") ; \L -> L
(("\"o" "\\\"o" "\\o" "\\oe") . "oe") ; "o,\"o,\o,\oe -> oe
(("\"O" "\\\"O" "\\O" "\\OE") . "Oe") ; "O,\"O,\O,\OE -> Oe
(("\"s" "\\\"s" "\\3") . "ss") ; "s,\"s,\3 -> ss
(("\"u" "\\\"u") . "ue") ; "u,\"u -> ue
(("\"U" "\\\"U") . "Ue") ; "U,\"U -> Ue
;; hyphen, accents
(("\\-" "\\`" "\\'" "\\^" "\\~" "\\=" "\\." "\\u" "\\v"
"\\H" "\\t" "\\c" "\\d" "\\b") . "")
;; space
(("~") . " ")))
;; more spaces
'(("[\s\t\n]*\\(?:\\\\\\)?[\s\t\n]+" . " ")
;; braces, quotes, concatenation.
("[`'\"{}#]" . "")))
"Alist of (OLD-REGEXP . NEW-STRING) pairs.
Used by the default values of `bibtex-autokey-name-change-strings' and
Used as default values of `bibtex-autokey-name-change-strings' and
`bibtex-autokey-titleword-change-strings'. Defaults to translating some
language specific characters to their ASCII transcriptions, and
removing any character accents.")
removing any accent characters.")
(defcustom bibtex-autokey-name-change-strings
bibtex-autokey-transcriptions

View file

@ -2914,16 +2914,17 @@ WHERE is provided the cell and table at that location is reported."
(defun table-generate-source (language &optional dest-buffer caption)
"Generate source of the current table in the specified language.
LANGUAGE is a symbol that specifies the language to describe the
structure of the table. It must be either `html', `latex' or `cals'.
The resulted source text is inserted into DEST-BUFFER and the buffer
object is returned. When DEST-BUFFER is omitted or nil the default
buffer specified in `table-dest-buffer-name' is used. In this case
the content of the default buffer is erased prior to the generation.
When DEST-BUFFER is non-nil it is expected to be either a destination
buffer or a name of the destination buffer. In this case the
generated result is inserted at the current point in the destination
buffer and the previously existing contents in the buffer are
untouched.
structure of the table. It must be either `html', `latex', `cals',
`wiki', or `mediawiki'.
The function inserts the resulting source text into DEST-BUFFER, and
returns the buffer object. When DEST-BUFFER is omitted or nil, the
function uses the default buffer specified in `table-dest-buffer-name'.
In this case, the function erases the default buffer prior to the
source generation.
When DEST-BUFFER is non-nil, it should be either a destination
buffer or a name of the destination buffer. In that case, the
function inserts the generated result at point in the destination
buffer, and leaves the previous contents of the buffer untouched.
References used for this implementation:

View file

@ -1222,23 +1222,24 @@ is non-nil."
(defun vc-cvs-ignore (file &optional directory _remove)
"Ignore FILE under CVS.
FILE is either absolute or relative to DIRECTORY. The basename
of FILE is written unmodified into the ignore file and is
FILE is either absolute or relative to DIRECTORY. The non-directory
part of FILE is written unmodified into the ignore file and is
therefore evaluated by CVS as an ignore pattern which follows
glob(7) syntax. If the pattern should match any of the special
characters ?*[\\\ literally, they must be escaped with a
characters `?*[\\' literally, they must be escaped with a
backslash.
CVS processes one ignore file for each subdirectory. Patterns
are separated by whitespace and only match files in the same
directory. Since FILE can be a relative filename with leading
diretories, FILE is expanded against DIRECTORY to determine the
correct absolute filename. The directory name of this path is
then used to determine the location of the ignore file. The base
name of this path is used as pattern for the ignore file.
directories, FILE is expanded against DIRECTORY to determine the
correct absolute filename. The directory part of the resulting name
is then used to determine the location of the ignore file. The
non-directory part of the name is used as pattern for the ignore file.
Since patterns are whitespace sparated, it is usually better to
replace spaces in filenames with question marks ?."
Since patterns are whitespace-separated, filenames containing spaces
cannot be represented directly. A work-around is to replace such
spaces with question marks."
(setq file (directory-file-name (expand-file-name file directory)))
(vc-cvs-append-to-ignore (file-name-directory file) (file-name-nondirectory file)))

View file

@ -879,9 +879,10 @@ If a prefix argument is given, ignore all marked files."
(vc-ignore (vc-dir-fileinfo->name filearg))
t))
vc-ewoc)
(vc-ignore
(file-relative-name (vc-dir-current-file))
default-directory)))
(let ((rel-dir (vc--ignore-base-dir)))
(vc-ignore
(file-relative-name (vc-dir-current-file) rel-dir)
rel-dir))))
(defun vc-dir-current-file ()
(let ((node (ewoc-locate vc-ewoc)))

View file

@ -1427,14 +1427,7 @@ When called interactively, prompt for a FILE to ignore, unless a
prefix argument is given, in which case prompt for a file FILE to
remove from the list of ignored files."
(interactive
(let* ((backend (vc-responsible-backend default-directory))
(rel-dir
(condition-case nil
(file-name-directory
(vc-call-backend backend 'find-ignore-file
default-directory))
(vc-not-supported
default-directory)))
(let* ((rel-dir (vc--ignore-base-dir))
(file (read-file-name "File to ignore: ")))
(when (and (file-name-absolute-p file)
(file-in-directory-p file rel-dir))
@ -1447,6 +1440,15 @@ remove from the list of ignored files."
(error "Unknown backend"))))
(vc-call-backend backend 'ignore file directory remove)))
(defun vc--ignore-base-dir ()
(let ((backend (vc-responsible-backend default-directory)))
(condition-case nil
(file-name-directory
(vc-call-backend backend 'find-ignore-file
default-directory))
(vc-not-supported
default-directory))))
(defun vc-default-ignore (backend file &optional directory remove)
"Ignore FILE under DIRECTORY (default is `default-directory').
FILE is a wildcard specification relative to DIRECTORY.

View file

@ -474,6 +474,11 @@ When `switch-to-buffer-obey-display-actions' is non-nil,
(tab-bar-new-tab))
(setq type 'tab)
(selected-window))
((eq dir 'new-frame)
(window--maybe-raise-frame
(make-frame-on-current-monitor pop-up-frame-alist))
(setq type 'frame)
(selected-window))
((eq dir 'same-window)
(selected-window))
(t (window-in-direction
@ -541,6 +546,12 @@ See the logic of the prefix ARG in `windmove-display-in-direction'."
(interactive "P")
(windmove-display-in-direction 'same-window arg))
;;;###autoload
(defun windmove-display-new-frame (&optional arg)
"Display the next buffer in a new frame."
(interactive "P")
(windmove-display-in-direction 'new-frame arg))
;;;###autoload
(defun windmove-display-new-tab (&optional arg)
"Display the next buffer in a new tab."
@ -562,6 +573,7 @@ Default value of MODIFIERS is `shift-meta'."
(global-set-key (vector (append modifiers '(up))) 'windmove-display-up)
(global-set-key (vector (append modifiers '(down))) 'windmove-display-down)
(global-set-key (vector (append modifiers '(?0))) 'windmove-display-same-window)
(global-set-key (vector (append modifiers '(?f))) 'windmove-display-new-frame)
(global-set-key (vector (append modifiers '(?t))) 'windmove-display-new-tab))

View file

@ -7891,15 +7891,15 @@ Info node `(elisp) Buffer Display Action Alists' for details of
such alists.
ALIST has to contain a `direction' entry whose value should be
one of `left', `above' (or `up'), `right' and `below' (or
'down'). Other values are usually interpreted as `below'.
one of `left', `above' (or `up'), `right' and `below' (or `down').
Other values are usually interpreted as `below'.
If ALIST also contains a `window' entry, its value specifies a
reference window. That value can be a special symbol like
'main' (which stands for the selected frame's main window) or
'root' (standings for the selected frame's root window) or an
`main' (which stands for the selected frame's main window) or
`root' (standings for the selected frame's root window) or an
arbitrary valid window. Any other value (or omitting the
'window' entry) means to use the selected window as reference
`window' entry) means to use the selected window as reference
window.
This function tries to reuse or split a window such that the
@ -8806,8 +8806,7 @@ parameters of FRAME."
(parent (frame-parent frame))
(monitor-attributes
(unless parent
(car (display-monitor-attributes-list
(frame-parameter frame 'display)))))
(frame-monitor-attributes frame)))
;; FRAME'S parent or display sizes. Used in connection
;; with margins.
(geometry
@ -8816,11 +8815,11 @@ parameters of FRAME."
(parent-or-display-width
(if parent
(frame-native-width parent)
(- (nth 2 geometry) (nth 0 geometry))))
(nth 2 geometry)))
(parent-or-display-height
(if parent
(frame-native-height parent)
(- (nth 3 geometry) (nth 1 geometry))))
(nth 3 geometry)))
;; FRAME's parent or workarea sizes. Used when no margins
;; are specified.
(parent-or-workarea
@ -8882,13 +8881,15 @@ parameters of FRAME."
(window--sanitize-margin
(nth 2 margins) left-margin
parent-or-display-width))
(nth 2 parent-or-workarea)))
(+ (nth 0 parent-or-workarea)
(nth 2 parent-or-workarea))))
(bottom-margin (if (nth 3 margins)
(- parent-or-display-height
(window--sanitize-margin
(nth 3 margins) top-margin
parent-or-display-height))
(nth 3 parent-or-workarea)))
(+ (nth 1 parent-or-workarea)
(nth 3 parent-or-workarea))))
;; Minimum and maximum sizes specified for FRAME.
(sizes (or (frame-parameter frame 'fit-frame-to-buffer-sizes)
fit-frame-to-buffer-sizes))
@ -9124,8 +9125,8 @@ accessible position."
;; wider than its frame's pixel width, its height
;; remains unaltered.
(width (+ (car (window-text-pixel-size
window (window-start) (point-max)
(frame-pixel-width)
window (window-start window) nil
(frame-pixel-width (window-frame window))
;; Add one line-height to assure that
;; we're on the safe side. This
;; overshoots when the first line below

65
m4/futimens.m4 Normal file
View file

@ -0,0 +1,65 @@
# serial 8
# See if we need to provide futimens replacement.
dnl Copyright (C) 2009-2020 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
# Written by Eric Blake.
AC_DEFUN([gl_FUNC_FUTIMENS],
[
AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
AC_CHECK_FUNCS_ONCE([futimens])
if test $ac_cv_func_futimens = no; then
HAVE_FUTIMENS=0
else
AC_CACHE_CHECK([whether futimens works],
[gl_cv_func_futimens_works],
[AC_RUN_IFELSE([AC_LANG_PROGRAM([[
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
]], [[struct timespec ts[2];
int fd = creat ("conftest.file", 0600);
struct stat st;
if (fd < 0) return 1;
ts[0].tv_sec = 1;
ts[0].tv_nsec = UTIME_OMIT;
ts[1].tv_sec = 1;
ts[1].tv_nsec = UTIME_NOW;
errno = 0;
if (futimens (AT_FDCWD, NULL) == 0) return 2;
if (errno != EBADF) return 3;
if (futimens (fd, ts)) return 4;
sleep (1);
ts[0].tv_nsec = UTIME_NOW;
ts[1].tv_nsec = UTIME_OMIT;
if (futimens (fd, ts)) return 5;
if (fstat (fd, &st)) return 6;
if (st.st_ctime < st.st_atime) return 7;
]])],
[gl_cv_func_futimens_works=yes],
[gl_cv_func_futimens_works=no],
[case "$host_os" in
# Guess no on glibc systems.
*-gnu* | gnu*) gl_cv_func_futimens_works="guessing no" ;;
# Guess no on musl systems.
*-musl*) gl_cv_func_futimens_works="guessing no" ;;
# Guess yes otherwise.
*) gl_cv_func_futimens_works="guessing yes" ;;
esac
])
rm -f conftest.file])
case "$gl_cv_func_futimens_works" in
*yes) ;;
*)
REPLACE_FUTIMENS=1
;;
esac
fi
])

View file

@ -95,6 +95,7 @@ AC_DEFUN([gl_EARLY],
# Code from module fstatat:
# Code from module fsusage:
# Code from module fsync:
# Code from module futimens:
# Code from module getdtablesize:
# Code from module getgroups:
# Code from module getloadavg:
@ -179,6 +180,7 @@ AC_DEFUN([gl_EARLY],
# Code from module unlocked-io:
# Code from module update-copyright:
# Code from module utimens:
# Code from module utimensat:
# Code from module vararrays:
# Code from module verify:
# Code from module vla:
@ -297,6 +299,11 @@ AC_DEFUN([gl_INIT],
gl_PREREQ_FSYNC
fi
gl_UNISTD_MODULE_INDICATOR([fsync])
gl_FUNC_FUTIMENS
if test $HAVE_FUTIMENS = 0 || test $REPLACE_FUTIMENS = 1; then
AC_LIBOBJ([futimens])
fi
gl_SYS_STAT_MODULE_INDICATOR([futimens])
gl_GETLOADAVG
if test $HAVE_GETLOADAVG = 0; then
AC_LIBOBJ([getloadavg])
@ -466,7 +473,11 @@ AC_DEFUN([gl_INIT],
gl_TIMESPEC
gl_UNISTD_H
gl_FUNC_GLIBC_UNLOCKED_IO
gl_UTIMENS
gl_FUNC_UTIMENSAT
if test $HAVE_UTIMENSAT = 0 || test $REPLACE_UTIMENSAT = 1; then
AC_LIBOBJ([utimensat])
fi
gl_SYS_STAT_MODULE_INDICATOR([utimensat])
AC_C_VARARRAYS
gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b=false
gl_gnulib_enabled_cloexec=false
@ -485,6 +496,7 @@ AC_DEFUN([gl_INIT],
gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7=false
gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c=false
gl_gnulib_enabled_strtoll=false
gl_gnulib_enabled_utimens=false
gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec=false
func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b ()
{
@ -663,6 +675,13 @@ AC_DEFUN([gl_INIT],
gl_gnulib_enabled_strtoll=true
fi
}
func_gl_gnulib_m4code_utimens ()
{
if ! $gl_gnulib_enabled_utimens; then
gl_UTIMENS
gl_gnulib_enabled_utimens=true
fi
}
func_gl_gnulib_m4code_682e609604ccaac6be382e4ee3a4eaec ()
{
if ! $gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec; then
@ -705,6 +724,9 @@ AC_DEFUN([gl_INIT],
if test $HAVE_FSTATAT = 0 || test $REPLACE_FSTATAT = 1; then
func_gl_gnulib_m4code_03e0aaad4cb89ca757653bd367a6ccb7
fi
if test $HAVE_FUTIMENS = 0 || test $REPLACE_FUTIMENS = 1; then
func_gl_gnulib_m4code_utimens
fi
if test $REPLACE_GETOPT = 1; then
func_gl_gnulib_m4code_be453cec5eecf5731a274f2de7f2db36
fi
@ -729,6 +751,15 @@ AC_DEFUN([gl_INIT],
if test $HAVE_TIMEGM = 0 || test $REPLACE_TIMEGM = 1; then
func_gl_gnulib_m4code_5264294aa0a5557541b53c8c741f7f31
fi
if test $HAVE_UTIMENSAT = 0 || test $REPLACE_UTIMENSAT = 1; then
func_gl_gnulib_m4code_260941c0e5dc67ec9e87d1fb321c300b
fi
if test $HAVE_UTIMENSAT = 0 || test $REPLACE_UTIMENSAT = 1; then
func_gl_gnulib_m4code_03e0aaad4cb89ca757653bd367a6ccb7
fi
if test $HAVE_UTIMENSAT = 0 || test $REPLACE_UTIMENSAT = 1; then
func_gl_gnulib_m4code_utimens
fi
m4_pattern_allow([^gl_GNULIB_ENABLED_])
AM_CONDITIONAL([gl_GNULIB_ENABLED_260941c0e5dc67ec9e87d1fb321c300b], [$gl_gnulib_enabled_260941c0e5dc67ec9e87d1fb321c300b])
AM_CONDITIONAL([gl_GNULIB_ENABLED_cloexec], [$gl_gnulib_enabled_cloexec])
@ -747,6 +778,7 @@ AC_DEFUN([gl_INIT],
AM_CONDITIONAL([gl_GNULIB_ENABLED_03e0aaad4cb89ca757653bd367a6ccb7], [$gl_gnulib_enabled_03e0aaad4cb89ca757653bd367a6ccb7])
AM_CONDITIONAL([gl_GNULIB_ENABLED_6099e9737f757db36c47fa9d9f02e88c], [$gl_gnulib_enabled_6099e9737f757db36c47fa9d9f02e88c])
AM_CONDITIONAL([gl_GNULIB_ENABLED_strtoll], [$gl_gnulib_enabled_strtoll])
AM_CONDITIONAL([gl_GNULIB_ENABLED_utimens], [$gl_gnulib_enabled_utimens])
AM_CONDITIONAL([gl_GNULIB_ENABLED_682e609604ccaac6be382e4ee3a4eaec], [$gl_gnulib_enabled_682e609604ccaac6be382e4ee3a4eaec])
# End of code from modules
m4_ifval(gl_LIBSOURCES_LIST, [
@ -956,6 +988,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/fsync.c
lib/ftoastr.c
lib/ftoastr.h
lib/futimens.c
lib/get-permissions.c
lib/getdtablesize.c
lib/getgroups.c
@ -1063,6 +1096,7 @@ AC_DEFUN([gl_FILE_LIST], [
lib/unlocked-io.h
lib/utimens.c
lib/utimens.h
lib/utimensat.c
lib/verify.h
lib/vla.h
lib/warn-on-use.h
@ -1103,6 +1137,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/fstatat.m4
m4/fsusage.m4
m4/fsync.m4
m4/futimens.m4
m4/getdtablesize.m4
m4/getgroups.m4
m4/getloadavg.m4
@ -1184,6 +1219,7 @@ AC_DEFUN([gl_FILE_LIST], [
m4/unistd_h.m4
m4/unlocked-io.m4
m4/utimens.m4
m4/utimensat.m4
m4/utimes.m4
m4/vararrays.m4
m4/warn-on-use.m4

69
m4/utimensat.m4 Normal file
View file

@ -0,0 +1,69 @@
# serial 6
# See if we need to provide utimensat replacement.
dnl Copyright (C) 2009-2020 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
# Written by Eric Blake.
AC_DEFUN([gl_FUNC_UTIMENSAT],
[
AC_REQUIRE([gl_SYS_STAT_H_DEFAULTS])
AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
AC_CHECK_FUNCS_ONCE([utimensat])
if test $ac_cv_func_utimensat = no; then
HAVE_UTIMENSAT=0
else
AC_CACHE_CHECK([whether utimensat works],
[gl_cv_func_utimensat_works],
[AC_RUN_IFELSE(
[AC_LANG_PROGRAM([[
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
]], [[int result = 0;
const char *f = "conftest.file";
if (close (creat (f, 0600)))
return 1;
/* Test whether the AT_SYMLINK_NOFOLLOW flag is supported. */
{
if (utimensat (AT_FDCWD, f, NULL, AT_SYMLINK_NOFOLLOW))
result |= 2;
}
/* Test whether UTIME_NOW and UTIME_OMIT work. */
{
struct timespec ts[2];
ts[0].tv_sec = 1;
ts[0].tv_nsec = UTIME_OMIT;
ts[1].tv_sec = 1;
ts[1].tv_nsec = UTIME_NOW;
if (utimensat (AT_FDCWD, f, ts, 0))
result |= 4;
}
sleep (1);
{
struct stat st;
struct timespec ts[2];
ts[0].tv_sec = 1;
ts[0].tv_nsec = UTIME_NOW;
ts[1].tv_sec = 1;
ts[1].tv_nsec = UTIME_OMIT;
if (utimensat (AT_FDCWD, f, ts, 0))
result |= 8;
if (stat (f, &st))
result |= 16;
else if (st.st_ctime < st.st_atime)
result |= 32;
}
return result;
]])],
[gl_cv_func_utimensat_works=yes],
[gl_cv_func_utimensat_works=no],
[gl_cv_func_utimensat_works="guessing yes"])])
if test "$gl_cv_func_utimensat_works" = no; then
REPLACE_UTIMENSAT=1
fi
fi
])

View file

@ -65,3 +65,5 @@ OMIT_GNULIB_MODULE_unistd = true
OMIT_GNULIB_MODULE_canonicalize-lgpl = true
OMIT_GNULIB_MODULE_fchmodat = true
OMIT_GNULIB_MODULE_lchmod = true
OMIT_GNULIB_MODULE_futimens = true
OMIT_GNULIB_MODULE_utimensat = true

View file

@ -164,4 +164,9 @@ int __cdecl __MINGW_NOTHROW fstatat (int, char const *,
struct stat *, int);
int __cdecl __MINGW_NOTHROW chmod (const char*, int);
/* Provide prototypes of library functions that are emulated on w32
and whose prototypes are usually found in sys/stat.h on POSIX
platforms. */
extern int utimensat (int, const char *, struct timespec const[2], int);
#endif /* INC_SYS_STAT_H_ */

View file

@ -105,6 +105,10 @@ gl_cv_func_fstatat_zero_flag=yes
ac_cv_func_fchmodat=yes
gl_cv_func_fchmodat_works="not-needed-so-yes"
ac_cv_func_lchmod=yes
ac_cv_func_futimens=not-needed
gl_cv_func_futimens_works="not-needed-so-yes"
ac_cv_func_utimensat=yes
gl_cv_func_utimensat_works=yes
# Aliased to _commit in ms-w32.h
ac_cv_func_fsync=yes
ac_cv_func_fdatasync=yes

View file

@ -818,6 +818,11 @@ fill_gstring_body (Lisp_Object gstring)
Lisp_Object header = AREF (gstring, 0);
ptrdiff_t len = LGSTRING_CHAR_LEN (gstring);
ptrdiff_t i;
struct font *font = NULL;
unsigned int code;
if (FONT_OBJECT_P (font_object))
font = XFONT_OBJECT (font_object);
for (i = 0; i < len; i++)
{
@ -832,10 +837,15 @@ fill_gstring_body (Lisp_Object gstring)
LGLYPH_SET_FROM (g, i);
LGLYPH_SET_TO (g, i);
LGLYPH_SET_CHAR (g, c);
if (FONT_OBJECT_P (font_object))
{
font_fill_lglyph_metrics (g, font_object);
}
if (font != NULL)
code = font->driver->encode_char (font, LGLYPH_CHAR (g));
else
code = FONT_INVALID_CODE;
if (code != FONT_INVALID_CODE)
{
font_fill_lglyph_metrics (g, font, code);
}
else
{
int width = XFIXNAT (CHAR_TABLE_REF (Vchar_width_table, c));

View file

@ -78,6 +78,7 @@ typedef bool bool_bf;
# define __has_attribute_no_address_safety_analysis false
# define __has_attribute_no_sanitize_address GNUC_PREREQ (4, 8, 0)
# define __has_attribute_no_sanitize_undefined GNUC_PREREQ (4, 9, 0)
# define __has_attribute_returns_nonnull GNUC_PREREQ (4, 9, 0)
# define __has_attribute_warn_unused_result GNUC_PREREQ (3, 4, 0)
#endif
@ -321,6 +322,12 @@ extern int emacs_setenv_TZ (char const *);
#define ATTRIBUTE_MALLOC_SIZE(args) ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE (args)
#if __has_attribute (returns_nonnull)
# define ATTRIBUTE_RETURNS_NONNULL __attribute__ ((returns_nonnull))
#else
# define ATTRIBUTE_RETURNS_NONNULL
#endif
/* Work around GCC bug 59600: when a function is inlined, the inlined
code may have its addresses sanitized even if the function has the
no_sanitize_address attribute. This bug is fixed in GCC 4.9.0 and

View file

@ -1262,14 +1262,17 @@ name, or nil if there is no such user. */)
if (q)
{
Lisp_Object login = Fuser_login_name (INT_TO_INTEGER (pw->pw_uid));
USE_SAFE_ALLOCA;
char *r = SAFE_ALLOCA (strlen (p) + SBYTES (login) + 1);
memcpy (r, p, q - p);
char *s = lispstpcpy (&r[q - p], login);
r[q - p] = upcase ((unsigned char) r[q - p]);
strcpy (s, q + 1);
full = build_string (r);
SAFE_FREE ();
if (!NILP (login))
{
USE_SAFE_ALLOCA;
char *r = SAFE_ALLOCA (strlen (p) + SBYTES (login) + 1);
memcpy (r, p, q - p);
char *s = lispstpcpy (&r[q - p], login);
r[q - p] = upcase ((unsigned char) r[q - p]);
strcpy (s, q + 1);
full = build_string (r);
SAFE_FREE ();
}
}
#endif /* AMPERSAND_FULL_NAME */

View file

@ -1974,7 +1974,6 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
/* This calls putenv and so must precede init_process_emacs. */
init_timefns ();
/* This sets Voperating_system_release, which init_process_emacs uses. */
init_editfns ();
/* These two call putenv. */

View file

@ -2077,7 +2077,7 @@ permissions. */)
report_file_error ("Copying permissions from", file);
case -3:
xsignal2 (Qfile_date_error,
build_string ("Resetting file times"), newname);
build_string ("Cannot set file date"), newname);
case -4:
report_file_error ("Copying permissions to", newname);
}
@ -2253,9 +2253,8 @@ permissions. */)
if (!NILP (keep_time))
{
struct timespec atime = get_stat_atime (&st);
struct timespec mtime = get_stat_mtime (&st);
if (set_file_times (ofd, SSDATA (encoded_newname), atime, mtime) != 0)
struct timespec ts[] = { get_stat_atime (&st), get_stat_mtime (&st) };
if (futimens (ofd, ts) != 0)
xsignal2 (Qfile_date_error,
build_string ("Cannot set file date"), newname);
}
@ -3430,39 +3429,41 @@ The value is an integer. */)
}
DEFUN ("set-file-times", Fset_file_times, Sset_file_times, 1, 2, 0,
DEFUN ("set-file-times", Fset_file_times, Sset_file_times, 1, 3, 0,
doc: /* Set times of file FILENAME to TIMESTAMP.
Set both access and modification times.
Return t on success, else nil.
Use the current time if TIMESTAMP is nil. TIMESTAMP is in the format of
`current-time'. */)
(Lisp_Object filename, Lisp_Object timestamp)
If optional FLAG is `nofollow', do not follow FILENAME if it is a
symbolic link. Set both access and modification times. Return t on
success, else nil. Use the current time if TIMESTAMP is nil.
TIMESTAMP is in the format of `current-time'. */)
(Lisp_Object filename, Lisp_Object timestamp, Lisp_Object flag)
{
Lisp_Object absname, encoded_absname;
Lisp_Object handler;
struct timespec t = lisp_time_argument (timestamp);
int nofollow = symlink_nofollow_flag (flag);
absname = Fexpand_file_name (filename, BVAR (current_buffer, directory));
struct timespec ts[2];
if (!NILP (timestamp))
ts[0] = ts[1] = lisp_time_argument (timestamp);
else
ts[0].tv_nsec = ts[1].tv_nsec = UTIME_NOW;
/* If the file name has special constructs in it,
call the corresponding file name handler. */
handler = Ffind_file_name_handler (absname, Qset_file_times);
Lisp_Object
absname = Fexpand_file_name (filename, BVAR (current_buffer, directory)),
handler = Ffind_file_name_handler (absname, Qset_file_times);
if (!NILP (handler))
return call3 (handler, Qset_file_times, absname, timestamp);
return call4 (handler, Qset_file_times, absname, timestamp, flag);
encoded_absname = ENCODE_FILE (absname);
Lisp_Object encoded_absname = ENCODE_FILE (absname);
{
if (set_file_times (-1, SSDATA (encoded_absname), t, t) != 0)
{
if (utimensat (AT_FDCWD, SSDATA (encoded_absname), ts, nofollow) != 0)
{
#ifdef MSDOS
/* Setting times on a directory always fails. */
if (file_directory_p (encoded_absname))
return Qnil;
/* Setting times on a directory always fails. */
if (file_directory_p (encoded_absname))
return Qnil;
#endif
report_file_error ("Setting file times", absname);
}
}
report_file_error ("Setting file times", absname);
}
return Qt;
}

View file

@ -4416,10 +4416,8 @@ DEFUN ("clear-font-cache", Fclear_font_cache, Sclear_font_cache, 0, 0, 0,
void
font_fill_lglyph_metrics (Lisp_Object glyph, Lisp_Object font_object)
font_fill_lglyph_metrics (Lisp_Object glyph, struct font *font, unsigned int code)
{
struct font *font = XFONT_OBJECT (font_object);
unsigned code = font->driver->encode_char (font, LGLYPH_CHAR (glyph));
struct font_metrics metrics;
LGLYPH_SET_CODE (glyph, code);

View file

@ -886,7 +886,7 @@ extern Lisp_Object font_update_drivers (struct frame *f, Lisp_Object list);
extern Lisp_Object font_range (ptrdiff_t, ptrdiff_t, ptrdiff_t *,
struct window *, struct face *,
Lisp_Object);
extern void font_fill_lglyph_metrics (Lisp_Object, Lisp_Object);
extern void font_fill_lglyph_metrics (Lisp_Object, struct font *, unsigned int);
extern Lisp_Object font_put_extra (Lisp_Object font, Lisp_Object prop,
Lisp_Object val);

View file

@ -367,8 +367,14 @@ fontset_add (Lisp_Object fontset, Lisp_Object range, Lisp_Object elt, Lisp_Objec
static int
fontset_compare_rfontdef (const void *val1, const void *val2)
{
return (RFONT_DEF_SCORE (*(Lisp_Object *) val1)
- RFONT_DEF_SCORE (*(Lisp_Object *) val2));
Lisp_Object v1 = *(Lisp_Object *) val1, v2 = *(Lisp_Object *) val2;
if (NILP (v1) && NILP (v2))
return 0;
else if (NILP (v1))
return INT_MIN;
else if (NILP (v2))
return INT_MAX;
return (RFONT_DEF_SCORE (v1) - RFONT_DEF_SCORE (v2));
}
/* Update a cons cell which has this form:
@ -400,6 +406,8 @@ reorder_font_vector (Lisp_Object font_group, struct font *font)
for (i = 0; i < size; i++)
{
Lisp_Object rfont_def = AREF (vec, i);
if (NILP (rfont_def))
continue;
Lisp_Object font_def = RFONT_DEF_FONT_DEF (rfont_def);
Lisp_Object font_spec = FONT_DEF_SPEC (font_def);
int score = RFONT_DEF_SCORE (rfont_def) & 0xFF;

View file

@ -1500,7 +1500,8 @@ DEFUN ("define-fringe-bitmap", Fdefine_fringe_bitmap, Sdefine_fringe_bitmap,
BITMAP is a symbol identifying the new fringe bitmap.
BITS is either a string or a vector of integers.
HEIGHT is height of bitmap. If HEIGHT is nil, use length of BITS.
WIDTH must be an integer between 1 and 16, or nil which defaults to 8.
WIDTH must be an integer from 1 to 16, or nil which defaults to 8. An
error is signaled if WIDTH is outside this range.
Optional fifth arg ALIGN may be one of `top', `center', or `bottom',
indicating the positioning of the bitmap relative to the rows where it
is used; the default is to center the bitmap. Fifth arg may also be a
@ -1535,7 +1536,9 @@ If BITMAP already exists, the existing definition is replaced. */)
else
{
CHECK_FIXNUM (width);
fb.width = max (0, min (XFIXNUM (width), 255));
fb.width = max (1, min (XFIXNUM (width), 16));
if (fb.width != XFIXNUM (width))
args_out_of_range (width, build_string ("Width must be from 1 to 16"));
}
fb.period = 0;

View file

@ -2834,16 +2834,21 @@ Any GnuTLS extension with ID up to 100
void
syms_of_gnutls (void)
{
DEFSYM (Qlibgnutls_version, "libgnutls-version");
Fset (Qlibgnutls_version,
DEFVAR_LISP ("libgnutls-version", Vlibgnutls_version,
doc: /* The version of libgnutls that Emacs was compiled with.
The version number is encoded as an integer with the major version in
the ten thousands place, minor version in the hundreds, and patch
level in the ones. For builds without libgnutls, the value is -1. */);
Vlibgnutls_version = make_fixnum
#ifdef HAVE_GNUTLS
make_fixnum (GNUTLS_VERSION_MAJOR * 10000
+ GNUTLS_VERSION_MINOR * 100
+ GNUTLS_VERSION_PATCH)
(GNUTLS_VERSION_MAJOR * 10000
+ GNUTLS_VERSION_MINOR * 100
+ GNUTLS_VERSION_PATCH)
#else
make_fixnum (-1)
(-1)
#endif
);
;
#ifdef HAVE_GNUTLS
gnutls_global_initialized = 0;
PDUMPER_IGNORE (gnutls_global_initialized);

View file

@ -298,7 +298,7 @@ rotate_right (INTERVAL A)
set_interval_parent (c, A);
/* A's total length is decreased by the length of B and its left child. */
A->total_length -= B->total_length - TOTAL_LENGTH (c);
A->total_length -= TOTAL_LENGTH (B) - TOTAL_LENGTH0 (c);
eassert (TOTAL_LENGTH (A) > 0);
eassert (LENGTH (A) > 0);
@ -349,7 +349,7 @@ rotate_left (INTERVAL A)
set_interval_parent (c, A);
/* A's total length is decreased by the length of B and its right child. */
A->total_length -= B->total_length - TOTAL_LENGTH (c);
A->total_length -= TOTAL_LENGTH (B) - TOTAL_LENGTH0 (c);
eassert (TOTAL_LENGTH (A) > 0);
eassert (LENGTH (A) > 0);
@ -723,13 +723,13 @@ previous_interval (register INTERVAL interval)
i->position - LEFT_TOTAL_LENGTH (i) \
- LENGTH (INTERVAL_PARENT (i))
/* Find the interval containing POS, given some non-NULL INTERVAL in
/* Find the interval containing POS, given some interval I in
the same tree. Note that we update interval->position in each
interval we traverse, assuming it is already correctly set for the
argument I. We don't assume that any other interval already has a
correctly set ->position. */
INTERVAL
update_interval (register INTERVAL i, ptrdiff_t pos)
update_interval (INTERVAL i, ptrdiff_t pos)
{
if (!i)
return NULL;
@ -739,7 +739,7 @@ update_interval (register INTERVAL i, ptrdiff_t pos)
if (pos < i->position)
{
/* Move left. */
if (pos >= i->position - TOTAL_LENGTH (i->left))
if (pos >= i->position - LEFT_TOTAL_LENGTH (i))
{
i->left->position = i->position - TOTAL_LENGTH (i->left)
+ LEFT_TOTAL_LENGTH (i->left);
@ -757,7 +757,7 @@ update_interval (register INTERVAL i, ptrdiff_t pos)
else if (pos >= INTERVAL_LAST_POS (i))
{
/* Move right. */
if (pos < INTERVAL_LAST_POS (i) + TOTAL_LENGTH (i->right))
if (pos < INTERVAL_LAST_POS (i) + RIGHT_TOTAL_LENGTH (i))
{
i->right->position = INTERVAL_LAST_POS (i)
+ LEFT_TOTAL_LENGTH (i->right);

View file

@ -96,24 +96,27 @@ struct interval
/* True if this interval has both left and right children. */
#define BOTH_KIDS_P(i) ((i)->left != NULL && (i)->right != NULL)
/* The total size of all text represented by this interval and all its
children in the tree. This is zero if the interval is null. */
#define TOTAL_LENGTH(i) ((i) == NULL ? 0 : (i)->total_length)
/* The total size of all text represented by the nonnull interval I
and all its children in the tree. */
#define TOTAL_LENGTH(i) ((i)->total_length)
/* Likewise, but also defined to be zero if I is null. */
#define TOTAL_LENGTH0(i) ((i) ? TOTAL_LENGTH (i) : 0)
/* The size of text represented by this interval alone. */
#define LENGTH(i) ((i)->total_length \
- TOTAL_LENGTH ((i)->right) \
- TOTAL_LENGTH ((i)->left))
#define LENGTH(i) (TOTAL_LENGTH (i) \
- RIGHT_TOTAL_LENGTH (i) \
- LEFT_TOTAL_LENGTH (i))
/* The position of the character just past the end of I. Note that
the position cache i->position must be valid for this to work. */
#define INTERVAL_LAST_POS(i) ((i)->position + LENGTH (i))
/* The total size of the left subtree of this interval. */
#define LEFT_TOTAL_LENGTH(i) ((i)->left ? (i)->left->total_length : 0)
#define LEFT_TOTAL_LENGTH(i) TOTAL_LENGTH0 ((i)->left)
/* The total size of the right subtree of this interval. */
#define RIGHT_TOTAL_LENGTH(i) ((i)->right ? (i)->right->total_length : 0)
#define RIGHT_TOTAL_LENGTH(i) TOTAL_LENGTH0 ((i)->right)
/* These macros are for dealing with the interval properties. */
@ -234,7 +237,7 @@ set_interval_plist (INTERVAL i, Lisp_Object plist)
/* Declared in alloc.c. */
extern INTERVAL make_interval (void);
extern INTERVAL make_interval (void) ATTRIBUTE_RETURNS_NONNULL;
/* Declared in intervals.c. */
@ -246,7 +249,8 @@ extern void traverse_intervals (INTERVAL, ptrdiff_t,
Lisp_Object);
extern void traverse_intervals_noorder (INTERVAL,
void (*) (INTERVAL, void *), void *);
extern INTERVAL split_interval_right (INTERVAL, ptrdiff_t);
extern INTERVAL split_interval_right (INTERVAL, ptrdiff_t)
ATTRIBUTE_RETURNS_NONNULL;
extern INTERVAL split_interval_left (INTERVAL, ptrdiff_t);
extern INTERVAL find_interval (INTERVAL, ptrdiff_t);
extern INTERVAL next_interval (INTERVAL);

View file

@ -1141,6 +1141,7 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
#ifdef NS_DRAW_TO_BUFFER
[NSGraphicsContext setCurrentContext:nil];
[view setNeedsDisplay:YES];
#else
block_input ();
@ -1194,12 +1195,6 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
/* clipping */
if (r)
{
#ifdef NS_IMPL_COCOA
int i;
for (i = 0 ; i < n ; i++)
[view setNeedsDisplayInRect:r[i]];
#endif
[[NSGraphicsContext currentContext] saveGraphicsState];
if (n == 2)
NSRectClipList (r, 2);
@ -1224,7 +1219,9 @@ static NSRect constrain_frame_rect(NSRect frameRect, bool isFullscreen)
gsaved = NO;
}
#ifdef NS_IMPL_GNUSTEP
#ifdef NS_DRAW_TO_BUFFER
[FRAME_NS_VIEW (f) setNeedsDisplay:YES];
#else
if (f != ns_updating_frame)
{
if (focus_view != NULL)

View file

@ -3692,14 +3692,12 @@ dump_unwind_cleanup (void *data)
Vprocess_environment = ctx->old_process_environment;
}
/* Return DUMP_OFFSET, making sure it is within the heap. */
static dump_off
/* Check that DUMP_OFFSET is within the heap. */
static void
dump_check_dump_off (struct dump_context *ctx, dump_off dump_offset)
{
eassert (dump_offset > 0);
if (ctx)
eassert (dump_offset < ctx->end_heap);
return dump_offset;
eassert (!ctx || dump_offset < ctx->end_heap);
}
static void
@ -3822,6 +3820,7 @@ decode_emacs_reloc (struct dump_context *ctx, Lisp_Object lreloc)
}
else
{
eassume (ctx); /* Pacify GCC 9.2.1 -O3 -Wnull-dereference. */
eassert (!dump_object_emacs_ptr (target_value));
reloc.u.dump_offset = dump_recall_object (ctx, target_value);
if (reloc.u.dump_offset <= 0)

View file

@ -8277,19 +8277,6 @@ init_process_emacs (int sockfd)
memset (datagram_address, 0, sizeof datagram_address);
#endif
#if defined (DARWIN_OS)
/* PTYs are broken on Darwin < 6, but are sometimes useful for interactive
processes. As such, we only change the default value. */
if (initialized)
{
char const *release = (STRINGP (Voperating_system_release)
? SSDATA (Voperating_system_release)
: 0);
if (!release || !release[0] || (release[0] < '7' && release[1] == '.')) {
Vprocess_connection_type = Qnil;
}
}
#endif
#endif /* subprocesses */
kbd_is_on_hold = 0;
}

View file

@ -2752,21 +2752,6 @@ emacs_perror (char const *message)
errno = err;
}
/* Set the access and modification time stamps of FD (a.k.a. FILE) to be
ATIME and MTIME, respectively.
FD must be either negative -- in which case it is ignored --
or a file descriptor that is open on FILE.
If FD is nonnegative, then FILE can be NULL. */
int
set_file_times (int fd, const char *filename,
struct timespec atime, struct timespec mtime)
{
struct timespec timespec[2];
timespec[0] = atime;
timespec[1] = mtime;
return fdutimens (fd, filename, timespec);
}
/* Rename directory SRCFD's entry SRC to directory DSTFD's entry DST.
This is like renameat except that it fails if DST already exists,
or if this operation is not supported atomically. Return 0 if

View file

@ -67,9 +67,6 @@ timespec_valid_p (struct timespec t)
return t.tv_nsec >= 0;
}
/* defined in sysdep.c */
extern int set_file_times (int, const char *, struct timespec, struct timespec);
/* defined in keyboard.c */
extern void set_waiting_for_input (struct timespec *);

View file

@ -421,6 +421,9 @@ decode_float_time (double t, struct lisp_time *result)
else if (flt_radix_power_size <= scale)
return isnan (t) ? EDOM : EOVERFLOW;
/* Compute TICKS, HZ such that TICKS / HZ exactly equals T, where HZ is
T's frequency or 1, whichever is greater. Here, frequency means
1/precision. Cache HZ values in flt_radix_power. */
double scaled = scalbn (t, scale);
eassert (trunc (scaled) == scaled);
ticks = double_to_integer (scaled);
@ -442,6 +445,7 @@ decode_float_time (double t, struct lisp_time *result)
static Lisp_Object
ticks_hz_list4 (Lisp_Object ticks, Lisp_Object hz)
{
/* mpz[0] = floor ((ticks * trillion) / hz). */
mpz_t const *zticks = bignum_integer (&mpz[0], ticks);
#if FASTER_TIMEFNS && TRILLION <= ULONG_MAX
mpz_mul_ui (mpz[0], *zticks, TRILLION);
@ -449,6 +453,9 @@ ticks_hz_list4 (Lisp_Object ticks, Lisp_Object hz)
mpz_mul (mpz[0], *zticks, ztrillion);
#endif
mpz_fdiv_q (mpz[0], mpz[0], *bignum_integer (&mpz[1], hz));
/* mpz[0] = floor (mpz[0] / trillion), with US = the high six digits of the
12-digit remainder, and PS = the low six digits. */
#if FASTER_TIMEFNS && TRILLION <= ULONG_MAX
unsigned long int fullps = mpz_fdiv_q_ui (mpz[0], mpz[0], TRILLION);
int us = fullps / 1000000;
@ -458,11 +465,14 @@ ticks_hz_list4 (Lisp_Object ticks, Lisp_Object hz)
int ps = mpz_fdiv_q_ui (mpz[1], mpz[1], 1000000);
int us = mpz_get_ui (mpz[1]);
#endif
/* mpz[0] = floor (mpz[0] / 1 << LO_TIME_BITS), with lo = remainder. */
unsigned long ulo = mpz_get_ui (mpz[0]);
if (mpz_sgn (mpz[0]) < 0)
ulo = -ulo;
int lo = ulo & ((1 << LO_TIME_BITS) - 1);
mpz_fdiv_q_2exp (mpz[0], mpz[0], LO_TIME_BITS);
return list4 (make_integer_mpz (), make_fixnum (lo),
make_fixnum (us), make_fixnum (ps));
}
@ -482,6 +492,7 @@ mpz_set_time (mpz_t rop, time_t t)
static void
timespec_mpz (struct timespec t)
{
/* mpz[0] = sec * TIMESPEC_HZ + nsec. */
mpz_set_ui (mpz[0], t.tv_nsec);
mpz_set_time (mpz[1], t.tv_sec);
mpz_addmul_ui (mpz[0], mpz[1], TIMESPEC_HZ);
@ -491,11 +502,14 @@ timespec_mpz (struct timespec t)
static Lisp_Object
timespec_ticks (struct timespec t)
{
/* For speed, use intmax_t arithmetic if it will do. */
intmax_t accum;
if (FASTER_TIMEFNS
&& !INT_MULTIPLY_WRAPV (t.tv_sec, TIMESPEC_HZ, &accum)
&& !INT_ADD_WRAPV (t.tv_nsec, accum, &accum))
return make_int (accum);
/* Fall back on bignum arithmetic. */
timespec_mpz (t);
return make_integer_mpz ();
}
@ -505,12 +519,19 @@ timespec_ticks (struct timespec t)
static Lisp_Object
lisp_time_hz_ticks (struct lisp_time t, Lisp_Object hz)
{
/* The idea is to return the floor of ((T.ticks * HZ) / T.hz). */
/* For speed, just return T.ticks if T.hz == HZ. */
if (FASTER_TIMEFNS && EQ (t.hz, hz))
return t.ticks;
/* Check HZ for validity. */
if (FIXNUMP (hz))
{
if (XFIXNUM (hz) <= 0)
invalid_hz (hz);
/* For speed, use intmax_t arithmetic if it will do. */
intmax_t ticks;
if (FASTER_TIMEFNS && FIXNUMP (t.ticks) && FIXNUMP (t.hz)
&& !INT_MULTIPLY_WRAPV (XFIXNUM (t.ticks), XFIXNUM (hz), &ticks))
@ -520,6 +541,7 @@ lisp_time_hz_ticks (struct lisp_time t, Lisp_Object hz)
else if (! (BIGNUMP (hz) && 0 < mpz_sgn (*xbignum_val (hz))))
invalid_hz (hz);
/* Fall back on bignum arithmetic. */
mpz_mul (mpz[0],
*bignum_integer (&mpz[0], t.ticks),
*bignum_integer (&mpz[1], hz));
@ -531,11 +553,17 @@ lisp_time_hz_ticks (struct lisp_time t, Lisp_Object hz)
static Lisp_Object
lisp_time_seconds (struct lisp_time t)
{
/* The idea is to return the floor of T.ticks / T.hz. */
if (!FASTER_TIMEFNS)
return lisp_time_hz_ticks (t, make_fixnum (1));
/* For speed, use EMACS_INT arithmetic if it will do. */
if (FIXNUMP (t.ticks) && FIXNUMP (t.hz))
return make_fixnum (XFIXNUM (t.ticks) / XFIXNUM (t.hz)
- (XFIXNUM (t.ticks) % XFIXNUM (t.hz) < 0));
/* For speed, inline what lisp_time_hz_ticks would do. */
mpz_fdiv_q (mpz[0],
*bignum_integer (&mpz[0], t.ticks),
*bignum_integer (&mpz[1], t.hz));
@ -577,6 +605,7 @@ frac_to_double (Lisp_Object numerator, Lisp_Object denominator)
&& intmax_numerator % intmax_denominator == 0)
return intmax_numerator / intmax_denominator;
/* Compute number of base-FLT_RADIX digits in numerator and denominator. */
mpz_t const *n = bignum_integer (&mpz[0], numerator);
mpz_t const *d = bignum_integer (&mpz[1], denominator);
ptrdiff_t ndig = mpz_sizeinbase (*n, FLT_RADIX);
@ -588,7 +617,8 @@ frac_to_double (Lisp_Object numerator, Lisp_Object denominator)
/* Scale with SCALE when doing integer division. That is, compute
(N * FLT_RADIX**SCALE) / D [or, if SCALE is negative, N / (D *
FLT_RADIX**-SCALE)] as a bignum, convert the bignum to double,
then divide the double by FLT_RADIX**SCALE. */
then divide the double by FLT_RADIX**SCALE. First scale N
(or scale D, if SCALE is negative) ... */
ptrdiff_t scale = ddig - ndig + DBL_MANT_DIG;
if (scale < 0)
{
@ -603,12 +633,12 @@ frac_to_double (Lisp_Object numerator, Lisp_Object denominator)
mpz_mul_2exp (mpz[0], *n, scale * LOG2_FLT_RADIX);
n = &mpz[0];
}
/* ... and then divide, with quotient Q and remainder R. */
mpz_t *q = &mpz[2];
mpz_t *r = &mpz[3];
mpz_tdiv_qr (*q, *r, *n, *d);
/* The amount to add to the absolute value of *Q so that truncating
/* The amount to add to the absolute value of Q so that truncating
it to double will round correctly. */
int incr;
@ -647,6 +677,7 @@ frac_to_double (Lisp_Object numerator, Lisp_Object denominator)
if (!FASTER_TIMEFNS || incr != 0)
(mpz_sgn (*n) < 0 ? mpz_sub_ui : mpz_add_ui) (*q, *q, incr);
/* Rescale the integer Q back to double. This step does not round. */
return scalbn (mpz_get_d (*q), -scale);
}
@ -895,6 +926,10 @@ lisp_to_timespec (struct lisp_time t)
mpz_t *q = &mpz[0];
mpz_t const *qt = q;
/* Floor-divide (T.ticks * TIMESPEC_HZ) by T.hz,
yielding quotient Q (tv_sec) and remainder NS (tv_nsec).
Return an invalid timespec if Q does not fit in time_t.
For speed, prefer fixnum arithmetic if it works. */
if (FASTER_TIMEFNS && EQ (t.hz, timespec_hz))
{
if (FIXNUMP (t.ticks))
@ -938,8 +973,8 @@ lisp_to_timespec (struct lisp_time t)
ns = mpz_fdiv_q_ui (*q, *q, TIMESPEC_HZ);
}
/* With some versions of MinGW, tv_sec is a 64-bit type, whereas
time_t is a 32-bit type. */
/* Check that Q fits in time_t, not merely in T.tv_sec. With some versions
of MinGW, tv_sec is a 64-bit type, whereas time_t is a 32-bit type. */
time_t sec;
if (mpz_time (*qt, &sec))
{
@ -1019,10 +1054,14 @@ lispint_arith (Lisp_Object a, Lisp_Object b, bool subtract)
{
if (EQ (b, make_fixnum (0)))
return a;
/* For speed, use EMACS_INT arithmetic if it will do. */
if (FIXNUMP (a))
return make_int (subtract
? XFIXNUM (a) - XFIXNUM (b)
: XFIXNUM (a) + XFIXNUM (b));
/* For speed, use mpz_add_ui/mpz_sub_ui if it will do. */
if (eabs (XFIXNUM (b)) <= ULONG_MAX)
{
((XFIXNUM (b) < 0) == subtract ? mpz_add_ui : mpz_sub_ui)
@ -1031,6 +1070,7 @@ lispint_arith (Lisp_Object a, Lisp_Object b, bool subtract)
}
}
/* Fall back on bignum arithmetic if necessary. */
if (!mpz_done)
(subtract ? mpz_sub : mpz_add) (mpz[0],
*bignum_integer (&mpz[0], a),
@ -1039,9 +1079,7 @@ lispint_arith (Lisp_Object a, Lisp_Object b, bool subtract)
}
/* Given Lisp operands A and B, add their values, and return the
result as a Lisp timestamp that is in (TICKS . HZ) form if either A
or B are in that form or are floats, (HI LO US PS) form otherwise.
Subtract instead of adding if SUBTRACT. */
result as a Lisp timestamp. Subtract instead of adding if SUBTRACT. */
static Lisp_Object
time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
{
@ -1124,21 +1162,22 @@ time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
(subtract ? mpz_submul : mpz_addmul) (*iticks, *fa, *nb);
/* Normalize iticks/ihz by dividing both numerator and
denominator by ig = gcd (iticks, ihz). However, if that
would cause the denominator to become less than hzmin,
rescale the denominator upwards from its ordinary value by
multiplying numerator and denominator so that the denominator
becomes at least hzmin. This rescaling avoids returning a
timestamp that is less precise than both a and b, or a
timestamp that looks obsolete when that might be a problem. */
denominator by ig = gcd (iticks, ihz). For speed, though,
skip this division if ihz = 1. */
mpz_t *ig = &mpz[3];
mpz_gcd (*ig, *iticks, *ihz);
if (!FASTER_TIMEFNS || mpz_cmp_ui (*ig, 1) > 0)
{
mpz_divexact (*iticks, *iticks, *ig);
mpz_divexact (*ihz, *ihz, *ig);
/* However, if dividing the denominator by ig would cause the
denominator to become less than hzmin, rescale the denominator
upwards by multiplying the normalized numerator and denominator
so that the resulting denominator becomes at least hzmin.
This rescaling avoids returning a timestamp that is less precise
than both a and b, or a timestamp that looks obsolete when that
might be a problem. */
if (!FASTER_TIMEFNS || mpz_cmp (*ihz, *hzmin) < 0)
{
/* Rescale straightforwardly. Although this might not
@ -1152,6 +1191,8 @@ time_arith (Lisp_Object a, Lisp_Object b, bool subtract)
mpz_mul (*ihz, *ihz, *rescale);
}
}
/* mpz[0] and iticks now correspond to the (HZ . TICKS) pair. */
hz = make_integer_mpz ();
mpz_swap (mpz[0], *iticks);
ticks = make_integer_mpz ();
@ -1213,6 +1254,8 @@ time_cmp (Lisp_Object a, Lisp_Object b)
if (EQ (a, b))
return 0;
/* Compare (ATICKS . AZ) to (BTICKS . BHZ) by comparing
ATICKS * BHZ to BTICKS * AHZ. */
struct lisp_time tb = lisp_time_struct (b, 0);
mpz_t const *za = bignum_integer (&mpz[0], ta.ticks);
mpz_t const *zb = bignum_integer (&mpz[1], tb.ticks);
@ -1490,6 +1533,7 @@ SEC is always an integer between 0 and 59.)
usage: (decode-time &optional TIME ZONE FORM) */)
(Lisp_Object specified_time, Lisp_Object zone, Lisp_Object form)
{
/* Compute broken-down local time LOCAL_TM from SPECIFIED_TIME and ZONE. */
struct lisp_time lt = lisp_time_struct (specified_time, 0);
struct timespec ts = lisp_to_timespec (lt);
if (! timespec_valid_p (ts))
@ -1504,6 +1548,7 @@ usage: (decode-time &optional TIME ZONE FORM) */)
if (!tm)
time_error (localtime_errno);
/* Let YEAR = LOCAL_TM.tm_year + TM_YEAR_BASE. */
Lisp_Object year;
if (FASTER_TIMEFNS
&& MOST_NEGATIVE_FIXNUM - TM_YEAR_BASE <= local_tm.tm_year
@ -1520,12 +1565,15 @@ usage: (decode-time &optional TIME ZONE FORM) */)
year = make_integer_mpz ();
}
/* Compute SEC from LOCAL_TM.tm_sec and HZ. */
Lisp_Object hz = lt.hz, sec;
if (EQ (hz, make_fixnum (1)) || !EQ (form, Qt))
sec = make_fixnum (local_tm.tm_sec);
else
{
Lisp_Object ticks; /* hz * tm_sec + mod (lt.ticks, hz) */
/* Let TICKS = HZ * LOCAL_TM.tm_sec + mod (LT.ticks, HZ)
and SEC = (TICKS . HZ). */
Lisp_Object ticks;
intmax_t n;
if (FASTER_TIMEFNS && FIXNUMP (lt.ticks) && FIXNUMP (hz)
&& !INT_MULTIPLY_WRAPV (XFIXNUM (hz), local_tm.tm_sec, &n)
@ -1655,6 +1703,7 @@ usage: (encode-time TIME &rest OBSOLESCENT-ARGUMENTS) */)
yeararg = args[5];
}
/* Let SEC = floor (LT.ticks / HZ), with SUBSECTICKS the remainder. */
struct lisp_time lt;
decode_lisp_time (secarg, 0, &lt, 0);
Lisp_Object hz = lt.hz, sec, subsecticks;

106
src/w32.c
View file

@ -3178,18 +3178,9 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2])
return _futime (fd, &_ut);
}
else
{
struct utimbuf ut;
ut.actime = timespec[0].tv_sec;
ut.modtime = timespec[1].tv_sec;
/* Call 'utime', which is implemented below, not the MS library
function, which fails on directories. */
return utime (file, &ut);
}
return utimensat (fd, file, timespec, 0);
}
/* ------------------------------------------------------------------------- */
/* IO support and wrapper functions for the Windows API. */
/* ------------------------------------------------------------------------- */
@ -4970,7 +4961,7 @@ convert_time (FILETIME ft)
}
static void
convert_from_time_t (time_t time, FILETIME * pft)
convert_from_timespec (struct timespec time, FILETIME * pft)
{
ULARGE_INTEGER tmp;
@ -4981,7 +4972,8 @@ convert_from_time_t (time_t time, FILETIME * pft)
}
/* time in 100ns units since 1-Jan-1601 */
tmp.QuadPart = (ULONGLONG) time * 10000000L + utc_base;
tmp.QuadPart =
(ULONGLONG) time.tv_sec * 10000000L + time.tv_nsec / 100 + utc_base;
pft->dwHighDateTime = tmp.HighPart;
pft->dwLowDateTime = tmp.LowPart;
}
@ -5648,8 +5640,8 @@ fstatat (int fd, char const *name, struct stat *st, int flags)
return stat_worker (name, st, ! (flags & AT_SYMLINK_NOFOLLOW));
}
/* Provide fstat and utime as well as stat for consistent handling of
file timestamps. */
/* Provide fstat and utimensat as well as stat for consistent handling
of file timestamps. */
int
fstat (int desc, struct stat * buf)
{
@ -5760,23 +5752,65 @@ fstat (int desc, struct stat * buf)
return 0;
}
/* A version of 'utime' which handles directories as well as
files. */
/* Emulate utimensat. */
int
utime (const char *name, struct utimbuf *times)
utimensat (int fd, const char *name, const struct timespec times[2], int flag)
{
struct utimbuf deftime;
struct timespec ltimes[2];
HANDLE fh;
FILETIME mtime;
FILETIME atime;
DWORD flags_and_attrs = FILE_FLAG_BACKUP_SEMANTICS;
/* Rely on a hack: an open directory is modeled as file descriptor 0.
This is good enough for the current usage in Emacs, but is fragile.
FIXME: Add proper support for utimensat.
Gnulib does this and can serve as a model. */
char fullname[MAX_UTF8_PATH];
if (fd != AT_FDCWD)
{
char lastc = dir_pathname[strlen (dir_pathname) - 1];
if (_snprintf (fullname, sizeof fullname, "%s%s%s",
dir_pathname, IS_DIRECTORY_SEP (lastc) ? "" : "/", name)
< 0)
{
errno = ENAMETOOLONG;
return -1;
}
name = fullname;
}
if (times == NULL)
{
deftime.modtime = deftime.actime = time (NULL);
times = &deftime;
memset (ltimes, 0, sizeof (ltimes));
ltimes[0] = ltimes[1] = current_timespec ();
}
else
{
if (times[0].tv_nsec == UTIME_OMIT && times[1].tv_nsec == UTIME_OMIT)
return 0; /* nothing to do */
if ((times[0].tv_nsec != UTIME_NOW && times[0].tv_nsec != UTIME_OMIT
&& !(0 <= times[0].tv_nsec && times[0].tv_nsec < 1000000000))
|| (times[1].tv_nsec != UTIME_NOW && times[1].tv_nsec != UTIME_OMIT
&& !(0 <= times[1].tv_nsec && times[1].tv_nsec < 1000000000)))
{
errno = EINVAL; /* reject invalid timespec values */
return -1;
}
memcpy (ltimes, times, sizeof (ltimes));
if (ltimes[0].tv_nsec == UTIME_NOW)
ltimes[0] = current_timespec ();
if (ltimes[1].tv_nsec == UTIME_NOW)
ltimes[1] = current_timespec ();
}
if (flag == AT_SYMLINK_NOFOLLOW)
flags_and_attrs |= FILE_FLAG_OPEN_REPARSE_POINT;
if (w32_unicode_filenames)
{
wchar_t name_utf16[MAX_PATH];
@ -5790,7 +5824,7 @@ utime (const char *name, struct utimbuf *times)
allows other processes to delete files inside it,
while we have the directory open. */
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
0, OPEN_EXISTING, flags_and_attrs, NULL);
}
else
{
@ -5801,13 +5835,26 @@ utime (const char *name, struct utimbuf *times)
fh = CreateFileA (name_ansi, FILE_WRITE_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
0, OPEN_EXISTING, flags_and_attrs, NULL);
}
if (fh != INVALID_HANDLE_VALUE)
{
convert_from_time_t (times->actime, &atime);
convert_from_time_t (times->modtime, &mtime);
if (!SetFileTime (fh, NULL, &atime, &mtime))
FILETIME *patime, *pmtime;
if (ltimes[0].tv_nsec == UTIME_OMIT)
patime = NULL;
else
{
convert_from_timespec (ltimes[0], &atime);
patime = &atime;
}
if (ltimes[1].tv_nsec == UTIME_OMIT)
pmtime = NULL;
else
{
convert_from_timespec (ltimes[1], &mtime);
pmtime = &mtime;
}
if (!SetFileTime (fh, NULL, patime, pmtime))
{
CloseHandle (fh);
errno = EACCES;
@ -6726,16 +6773,16 @@ w32_copy_file (const char *from, const char *to,
FIXME? */
else if (!keep_time)
{
struct timespec now;
struct timespec tnow[2];
DWORD attributes;
tnow[0] = tnow[1] = current_timespec ();
if (w32_unicode_filenames)
{
/* Ensure file is writable while its times are set. */
attributes = GetFileAttributesW (to_w);
SetFileAttributesW (to_w, attributes & ~FILE_ATTRIBUTE_READONLY);
now = current_timespec ();
if (set_file_times (-1, to, now, now))
if (utimensat (AT_FDCWD, to, tnow, 0))
{
/* Restore original attributes. */
SetFileAttributesW (to_w, attributes);
@ -6750,8 +6797,7 @@ w32_copy_file (const char *from, const char *to,
{
attributes = GetFileAttributesA (to_a);
SetFileAttributesA (to_a, attributes & ~FILE_ATTRIBUTE_READONLY);
now = current_timespec ();
if (set_file_times (-1, to, now, now))
if (utimensat (AT_FDCWD, to, tnow, 0))
{
SetFileAttributesA (to_a, attributes);
if (acl)

View file

@ -4701,6 +4701,10 @@ static short temp_buffer[100];
/* Temporarily store lead byte of DBCS input sequences. */
static char dbcs_lead = 0;
/* Temporarily store pending UTF-16 high surrogate unit and the modifiers. */
static unsigned short utf16_high;
static DWORD utf16_high_modifiers;
/**
mouse_or_wdesc_frame: When not dropping and the mouse was grabbed
for DPYINFO, return the frame where the mouse was seen last. If
@ -4912,9 +4916,45 @@ w32_read_socket (struct terminal *terminal,
XSETFRAME (inev.frame_or_window, f);
inev.timestamp = msg.msg.time;
if (utf16_high
&& (msg.msg.message != WM_UNICHAR
|| UTF_16_HIGH_SURROGATE_P (msg.msg.wParam)))
{
/* Flush the pending high surrogate if the low one
isn't coming. (This should never happen, but I
have paranoia about this stuff.) */
struct input_event inev1;
inev1.modifiers = utf16_high_modifiers;
inev1.code = utf16_high;
inev1.timestamp = inev.timestamp;
inev1.arg = Qnil;
kbd_buffer_store_event_hold (&inev1, hold_quit);
utf16_high = 0;
utf16_high_modifiers = 0;
}
if (msg.msg.message == WM_UNICHAR)
{
inev.code = msg.msg.wParam;
/* Handle UTF-16 encoded codepoint above the BMP.
This is needed to support Emoji input from input
panel popped up by "Win+." shortcut. */
if (UTF_16_HIGH_SURROGATE_P (msg.msg.wParam))
{
utf16_high = msg.msg.wParam;
utf16_high_modifiers = inev.modifiers;
inev.kind = NO_EVENT;
break;
}
else if (UTF_16_LOW_SURROGATE_P (msg.msg.wParam)
&& utf16_high)
{
inev.code = surrogates_to_codepoint (msg.msg.wParam,
utf16_high);
utf16_high = 0;
utf16_high_modifiers = 0;
}
else
inev.code = msg.msg.wParam;
}
else if (msg.msg.wParam < 256)
{

View file

@ -31441,6 +31441,10 @@ show_mouse_face (Mouse_HLInfo *hlinfo, enum draw_glyphs_face draw)
struct window *w = XWINDOW (hlinfo->mouse_face_window);
struct frame *f = XFRAME (WINDOW_FRAME (w));
/* Don't bother doing anything if we are on a wrong frame. */
if (f != hlinfo->mouse_face_mouse_frame)
return;
if (/* If window is in the process of being destroyed, don't bother
to do anything. */
w->current_matrix != NULL

View file

@ -42,13 +42,24 @@
(ert-deftest rx-or ()
(should (equal (rx (or "ab" (| "c" nonl) "de"))
"ab\\|c\\|.\\|de"))
(should (equal (rx (or "ab" "abc" "a"))
(should (equal (rx (or "ab" "abc" ?a))
"\\(?:a\\(?:bc?\\)?\\)"))
(should (equal (rx (or "ab" (| (or "abcd" "abcde")) (or "a" "abc")))
"\\(?:a\\(?:b\\(?:c\\(?:de?\\)?\\)?\\)?\\)"))
(should (equal (rx (or "a" (eval (string ?a ?b))))
"\\(?:ab?\\)"))
(should (equal (rx (| nonl "a") (| "b" blank))
"\\(?:.\\|a\\)\\(?:b\\|[[:blank:]]\\)"))
(should (equal (rx (|))
"\\`a\\`")))
(ert-deftest rx-def-in-or ()
(rx-let ((a b)
(b (or "abc" c))
(c ?a))
(should (equal (rx (or a (| "ab" "abcde") "abcd"))
"\\(?:a\\(?:b\\(?:c\\(?:de?\\)?\\)?\\)?\\)"))))
(ert-deftest rx-char-any ()
"Test character alternatives with `]' and `-' (Bug#25123)."
(should (equal
@ -130,7 +141,10 @@
(should (equal (rx (any "") (not (any "")))
"\\`a\\`[^z-a]"))
(should (equal (rx (any space ?a digit space))
"[a[:space:][:digit:]]")))
"[a[:space:][:digit:]]"))
(should (equal (rx (not "\n") (not ?\n) (not (any "\n")) (not-char ?\n)
(| (not (in "a\n")) (not (char ?\n (?b . ?b)))))
".....")))
(ert-deftest rx-pcase ()
(should (equal (pcase "a 1 2 3 1 1 b"
@ -298,7 +312,13 @@
(not (any "a-k"))))
"[^abh-k]"))
(should (equal (rx (or ?f (any "b-e") "a") (not (or ?x "y" (any "s-w"))))
"[a-f][^s-y]")))
"[a-f][^s-y]"))
(should (equal (rx (not (or (in "abc") (char "bcd"))))
"[^a-d]"))
(should (equal (rx (or (not (in "abc")) (not (char "bcd"))))
"[^bc]"))
(should (equal (rx (or "x" (? "yz")))
"x\\|\\(?:yz\\)?")))
(ert-deftest rx-def-in-charset-or ()
(rx-let ((a (any "badc"))

View file

@ -219,7 +219,8 @@ remote case we return always t."
(or file-notify--library
(file-remote-p temporary-file-directory)))
(defvar file-notify--test-remote-enabled-checked nil
(defvar file-notify--test-remote-enabled-checked
(if (getenv "EMACS_HYDRA_CI") '(t . nil))
"Cached result of `file-notify--test-remote-enabled'.
If the function did run, the value is a cons cell, the `cdr'
being the result.")
@ -771,9 +772,9 @@ delivered."
(copy-file file-notify--test-tmpfile file-notify--test-tmpfile1)
;; The next two events shall not be visible.
(file-notify--test-read-event)
(set-file-modes file-notify--test-tmpfile 000)
(set-file-modes file-notify--test-tmpfile 000 'nofollow)
(file-notify--test-read-event)
(set-file-times file-notify--test-tmpfile '(0 0))
(set-file-times file-notify--test-tmpfile '(0 0) 'nofollow)
(file-notify--test-read-event)
(delete-directory file-notify--test-tmpdir 'recursive))
(file-notify-rm-watch file-notify--test-desc)
@ -864,9 +865,9 @@ delivered."
(write-region
"any text" nil file-notify--test-tmpfile nil 'no-message)
(file-notify--test-read-event)
(set-file-modes file-notify--test-tmpfile 000)
(set-file-modes file-notify--test-tmpfile 000 'nofollow)
(file-notify--test-read-event)
(set-file-times file-notify--test-tmpfile '(0 0))
(set-file-times file-notify--test-tmpfile '(0 0) 'nofollow)
(file-notify--test-read-event)
(delete-file file-notify--test-tmpfile))
(file-notify-rm-watch file-notify--test-desc)

View file

@ -1003,9 +1003,9 @@ unquoted file names."
(ert-deftest files-tests-file-name-non-special-set-file-times ()
(files-tests--with-temp-non-special (tmpfile nospecial)
(set-file-times nospecial))
(set-file-times nospecial nil 'nofollow))
(files-tests--with-temp-non-special-and-file-name-handler (tmpfile nospecial)
(should-error (set-file-times nospecial))))
(should-error (set-file-times nospecial nil 'nofollow))))
(ert-deftest files-tests-file-name-non-special-set-visited-file-modtime ()
(files-tests--with-temp-non-special (tmpfile nospecial)

View file

@ -3743,7 +3743,8 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(file-attributes tmp-name1))))
;; Skip the test, if the remote handler is not able to set
;; the correct time.
(skip-unless (set-file-times tmp-name1 (seconds-to-time 1)))
(skip-unless (set-file-times tmp-name1 (seconds-to-time 1)
'nofollow))
;; Dumb remote shells without perl(1) or stat(1) are not
;; able to return the date correctly. They say "don't know".
(unless (tramp-compat-time-equal-p