commit 0a3f8da6e1a56ada409cf1677ac40fcc75a8a33c (HEAD, refs/remotes/origin/master) Author: Paul Eggert Date: Sun Mar 8 00:25:15 2020 -0800 Simplify run-at-time * lisp/emacs-lisp/timer.el (run-at-time): Remove unnecessary test (Bug#39944). diff --git a/lisp/emacs-lisp/timer.el b/lisp/emacs-lisp/timer.el index 9eb8feed0f..61fd05cbb8 100644 --- a/lisp/emacs-lisp/timer.el +++ b/lisp/emacs-lisp/timer.el @@ -378,9 +378,6 @@ This function returns a timer object which you can use in (decoded-time-year now) (decoded-time-zone now))))))) - (or (time-equal-p time time) - (error "Invalid time format")) - (let ((timer (timer-create))) (timer-set-time timer time repeat) (timer-set-function timer function args) commit 4415534ef01309417e8f552eb4c075095603f2f3 Merge: e4fb95fa18 0a3682a566 Author: Paul Eggert Date: Sun Mar 8 00:20:57 2020 -0800 Merge from origin/emacs-27 0a3682a566 * src/timefns.c: Add comments. b16ba4041d ; lisp/emacs-lisp/seq.el: Explain why we don't use cl-lib ... 3cbf4cb796 Eliminate use of cl-concatenate in 'seq' package 363d927086 Fix bug with JIT stealth timers 818333c85a * doc/lispref/os.texi (time-subtract): Doc fix. commit 0a3682a566d5563e3d57defe49359cee236e0274 (refs/remotes/origin/emacs-27) Author: Paul Eggert Date: Sun Mar 8 00:16:17 2020 -0800 * src/timefns.c: Add comments. diff --git a/src/timefns.c b/src/timefns.c index a08d3b816f..8e2bb214ed 100644 --- a/src/timefns.c +++ b/src/timefns.c @@ -491,11 +491,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 +508,17 @@ timespec_ticks (struct timespec t) static Lisp_Object lisp_time_hz_ticks (struct lisp_time t, Lisp_Object hz) { + /* For speed, just return TICKS if T is (TICKS . 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 +528,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)); @@ -533,9 +542,13 @@ lisp_time_seconds (struct lisp_time t) { 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)); @@ -1116,21 +1129,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 @@ -1144,6 +1158,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 (); commit e4fb95fa18072cedb021a82f7aa0e79fa6ca387a Author: Stefan Monnier Date: Sat Mar 7 23:28:12 2020 -0500 * lisp/emacs-lisp/bytecomp.el: Drop warning for loading into Emacs<23 Stash the major version of the compiling Emacs such that the loading Emacs can later detect when loading a file compiled by a too-new Emacs. (byte-compile-fix-header): Remove. (byte-compile-from-buffer): Don't call it any more. (byte-compile-insert-header): Stash the emacs-major-version in it. Don't leave space for `byte-compile-fix-header`. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 63348456a1..4f01918bdb 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2140,50 +2140,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." @@ -2201,7 +2160,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" @@ -2213,16 +2184,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 commit b16ba4041db928826df5f58e9bfac9fb38208145 Author: Noam Postavsky Date: Sat Mar 7 18:45:23 2020 -0500 ; lisp/emacs-lisp/seq.el: Explain why we don't use cl-lib here diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 629a7a5fb3..e3037a7190 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -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. commit 3cbf4cb79600ade39a186f31448e56e0e6fdd364 Author: Andrew Eggenberger Date: Thu Feb 27 21:43:47 2020 -0600 Eliminate use of cl-concatenate in 'seq' package Fixes (Bug#39761) by making cl-extra dependent on seq rather than vice versa. * lisp/emacs-lisp/seq.el (seq-concatenate): Move cl-concatenate's code here instead of calling it. * lisp/emacs-lisp/cl-extra.el (cl-concatenate): Use cl-concatenate. Copyright-paperwork-exempt: yes diff --git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el index e3dabdfcef..e9bfe8df5f 100644 --- a/lisp/emacs-lisp/cl-extra.el +++ b/lisp/emacs-lisp/cl-extra.el @@ -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. diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el index 0b946dd736..629a7a5fb3 100644 --- a/lisp/emacs-lisp/seq.el +++ b/lisp/emacs-lisp/seq.el @@ -285,7 +285,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. commit 6ce20525585cc9c4c865cfdd32b43ab268bb17ec Author: Glenn Morris Date: Sat Mar 7 12:16:44 2020 -0800 Skip filenotify tests on hydra.nixos.org They frequently hang for hours. * test/lisp/filenotify-tests.el (file-notify--test-remote-enabled-checked): Default to off on hydra. diff --git a/test/lisp/filenotify-tests.el b/test/lisp/filenotify-tests.el index a184fabb9f..42d86ee153 100644 --- a/test/lisp/filenotify-tests.el +++ b/test/lisp/filenotify-tests.el @@ -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.") commit 5d4cf1fef85bc24bc4cd9705ebb14150263ad707 Author: Paul Eggert Date: Sat Mar 7 12:04:05 2020 -0800 Add ‘nofollow’ flag to set-file-times This is a companion to the recent set-file-modes patch. It adds support for a ‘nofollow’ flag to set-file-times (Bug#39773). Like the set-file-modes patch, it needs work in the w32 port. * admin/merge-gnulib (GNULIB_MODULES): Add futimens, utimensat. Remove utimens. * doc/lispref/files.texi (Changing Files): * etc/NEWS: Mention the change. * lib/gnulib.mk.in, m4/gnulib-comp.m4: Regenerate. * lisp/files.el (copy-directory): * lisp/gnus/gnus-cloud.el (gnus-cloud-replace-file): * lisp/net/tramp-adb.el (tramp-adb-handle-copy-file): * lisp/net/tramp-smb.el (tramp-smb-handle-copy-file): * lisp/tar-mode.el (tar-copy): * test/lisp/filenotify-tests.el (file-notify-test03-events): * test/lisp/files-tests.el: (files-tests-file-name-non-special-set-file-times): * test/lisp/net/tramp-tests.el (tramp-test22-file-times): When setting file times, avoid following symbolic links when the file is not supposed to be a symbolic link. * lib/futimens.c, lib/utimensat.c, m4/futimens.m4, m4/utimensat.m4: New files, copied from Gnulib. * lisp/gnus/gnus-cloud.el (gnus-cloud-replace-file): When creating a file that is not supposed to exist already, use the excl flag to check this. * lisp/net/tramp-adb.el (tramp-adb-handle-set-file-times): * lisp/net/tramp-sh.el (tramp-sh-handle-set-file-times): * lisp/net/tramp-sudoedit.el (tramp-sudoedit-handle-set-file-times): Accept an optional FLAG arg that is currently ignored, and add a FIXME comment for it. * lisp/net/tramp-gvfs.el (tramp-gvfs-handle-set-file-times): * src/fileio.c (Fset_file_times): Support an optional FLAG arg. * src/fileio.c (Fcopy_file): Use futimens instead of set_file_times, as it’s simpler and is a POSIX API. * src/sysdep.c (set_file_times): Move from here ... * src/w32.c (set_file_times): ... to here, and make it static, since it is now used only in w32.c. Presumably w32.c should also add support for futimens and utimensat (the POSIX APIs, which Emacs now uses) and it can remove fdutimens (the Gnulib API, which Emacs no longer uses). diff --git a/admin/merge-gnulib b/admin/merge-gnulib index 557119441e..768e5051f0 100755 --- a/admin/merge-gnulib +++ b/admin/merge-gnulib @@ -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 ' diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index a69a4e5dd3..b3ad9b9964 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi @@ -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 diff --git a/etc/NEWS b/etc/NEWS index fcdf6dbe24..47b87afbc6 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -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". diff --git a/lib/futimens.c b/lib/futimens.c new file mode 100644 index 0000000000..83fb27cb6a --- /dev/null +++ b/lib/futimens.c @@ -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 . */ + +/* written by Eric Blake */ + +#include + +#include + +#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); +} diff --git a/lib/gnulib.mk.in b/lib/gnulib.mk.in index d4dc6a3df3..e90d2e3904 100644 --- a/lib/gnulib.mk.in +++ b/lib/gnulib.mk.in @@ -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)) diff --git a/lib/utimensat.c b/lib/utimensat.c new file mode 100644 index 0000000000..63788d5648 --- /dev/null +++ b/lib/utimensat.c @@ -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 . */ + +/* written by Eric Blake */ + +#include + +/* Specification. */ +#include + +#include +#include +#include + +#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 diff --git a/lisp/files.el b/lisp/files.el index 2e7694d767..8ce0187f5b 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -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. diff --git a/lisp/gnus/gnus-cloud.el b/lisp/gnus/gnus-cloud.el index 4d8764bacc..da6231d733 100644 --- a/lisp/gnus/gnus-cloud.el +++ b/lisp/gnus/gnus-cloud.el @@ -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)) diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index 2c9674fa36..7ee740f93c 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -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) diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index 3ce7bbbd4a..1ad57c59a5 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el @@ -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))))) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 84b8191bd3..560941c4d5 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -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) diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 42954cbda3..d91362c879 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -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." diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el index 7d8c8a9061..c054f405e3 100644 --- a/lisp/net/tramp-sudoedit.el +++ b/lisp/net/tramp-sudoedit.el @@ -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) diff --git a/lisp/tar-mode.el b/lisp/tar-mode.el index 97d883eebd..a3c1715b1e 100644 --- a/lisp/tar-mode.el +++ b/lisp/tar-mode.el @@ -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) diff --git a/m4/futimens.m4 b/m4/futimens.m4 new file mode 100644 index 0000000000..dc5cfa9411 --- /dev/null +++ b/m4/futimens.m4 @@ -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 +#include +#include +#include +]], [[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 +]) diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 1465ce811b..3228aa42b5 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -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 diff --git a/m4/utimensat.m4 b/m4/utimensat.m4 new file mode 100644 index 0000000000..2bc1bfebb5 --- /dev/null +++ b/m4/utimensat.m4 @@ -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 +#include +#include +]], [[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 +]) diff --git a/src/fileio.c b/src/fileio.c index 2532f5233c..82fd798920 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -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; } diff --git a/src/sysdep.c b/src/sysdep.c index e8e8bbfb50..149d80f19e 100644 --- a/src/sysdep.c +++ b/src/sysdep.c @@ -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 diff --git a/src/systime.h b/src/systime.h index 00ca4a1c58..b59a3d1c69 100644 --- a/src/systime.h +++ b/src/systime.h @@ -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 *); diff --git a/src/w32.c b/src/w32.c index cf1a3b3767..40f286ad6c 100644 --- a/src/w32.c +++ b/src/w32.c @@ -3189,6 +3189,21 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2]) } } +/* 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. */ +static 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); +} + /* ------------------------------------------------------------------------- */ /* IO support and wrapper functions for the Windows API. */ diff --git a/test/lisp/filenotify-tests.el b/test/lisp/filenotify-tests.el index 39156fbb5d..a184fabb9f 100644 --- a/test/lisp/filenotify-tests.el +++ b/test/lisp/filenotify-tests.el @@ -771,9 +771,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 +864,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) diff --git a/test/lisp/files-tests.el b/test/lisp/files-tests.el index ac56a7732f..05d9ceebf1 100644 --- a/test/lisp/files-tests.el +++ b/test/lisp/files-tests.el @@ -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) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index be0f418c94..dcf376e70b 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -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 commit 9f4b260c2b98ea05a02e0ab7213156ce2e60e5a9 Author: Paul Eggert Date: Sat Mar 7 11:58:20 2020 -0800 Update from Gnulib This incorporates: 2020-03-07 open, openat: port to (O_RDWR | O_RDONLY) != 0 * lib/open.c: Copy from Gnulib. diff --git a/lib/open.c b/lib/open.c index 487194f665..bb180fde29 100644 --- a/lib/open.c +++ b/lib/open.c @@ -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] == '/') commit 363d927086dbdc4e5073393889b76eb0470785f4 Author: Paul Eggert Date: Sat Mar 7 09:47:03 2020 -0800 Fix bug with JIT stealth timers * lisp/emacs-lisp/timer.el (run-at-time): Don’t assume that Lisp time values must be conses (Bug#39944). diff --git a/lisp/emacs-lisp/timer.el b/lisp/emacs-lisp/timer.el index 74a94957e7..9eb8feed0f 100644 --- a/lisp/emacs-lisp/timer.el +++ b/lisp/emacs-lisp/timer.el @@ -378,7 +378,7 @@ This function returns a timer object which you can use in (decoded-time-year now) (decoded-time-zone now))))))) - (or (consp time) + (or (time-equal-p time time) (error "Invalid time format")) (let ((timer (timer-create))) commit 818333c85a513dc2d0ae9ee00ecde983c4fe0269 Author: Paul Eggert Date: Sat Mar 7 09:30:19 2020 -0800 * doc/lispref/os.texi (time-subtract): Doc fix. diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi index 201ca18c1e..92aaf24b85 100644 --- a/doc/lispref/os.texi +++ b/doc/lispref/os.texi @@ -1978,10 +1978,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}. commit 3274b8090bf18dec00b6ce45d6a01bf5263982ed Merge: c996fe1ec6 72f87f8873 Author: Glenn Morris Date: Sat Mar 7 07:50:28 2020 -0800 Merge from origin/emacs-27 72f87f8873 (origin/emacs-27) NS port documentation updates 5b19db98ad ; * etc/NEWS: correctly describe what fido-mode is fc47e3ad99 Let fido-mode users force a minibuffer-exit e734961d4c icomplete-fido-exit: New command for the M-j binding 335a9bd215 minibuffer-force-complete-and-exit: Allow input with no ma... 34132d4bf6 ; * etc/NEWS: Mark 2 entries as fully documented. d28b73841b ; * etc/NEWS: Fix the 'mml-secure-openpgp-sign-with-sender... d1d56a9fd9 ; * etc/NEWS: 'thunk-let' and 'thunk-let*' are fully docum... fc4f4efabf ; * etc/NEWS: No need to document vc-hg and mergebase chan... 9e8456cf0f ; * etc/NEWS: No need to document changes in Octave mode. 25b4d6fa28 ; * etc/NEWS: No need to document changes in map.el and se... fc4d0f86da ; * etc/NEWS: No need to document Ido news. d4ac478cb3 ; * etc/NEWS: No need to document news of doc-view.el. 08c042bd26 Document that 'byte-compile-dynamic' is obsolete 512b66abd7 ; * etc/NEWS: No need to document 'goto-address-uri-scheme... 3103c01c3e ; * etc/NEWS: Formatting fixes. 98306fdfb8 ; * etc/NEWS: No need to document deprecation of 'cl'. 6281ed58be ; * etc/NEWS: No need to document the change in 'list-proc... e252341e11 ; * etc/NEWS: 'backup-by-copying-when-privileged-mismatch'... ec5a267ddc ; * etc/NEWS: Mark 'byte-count-to-string-function' as undo... 89307ebccd ; * etc/NEWS: Mark 'completion-common-part' face entry as ... fdbe7cacfb Document the changes in 'read-answer' 10c58356e4 Document changes in lexical-binding 5cb312b5b9 Update ERC mailing list address cb1877321b Use regexp-opt to define bibtex-autokey-transcriptions. (... 3f9c340de0 Improve documentation of 'table-generate-source' 33b31dc314 Attempt to avoid rare segfaults in show_mouse_face 88c6db9196 Avoid crashes when a fontset has strange entries 1814c7e158 Fix rx error with ? and ?? 40fb20061e * lisp/emacs-lisp/rx.el (rx--string-to-intervals): Fix err... 08d7d28d35 Fix args in 'window-text-pixel-size' call in 'fit-window-t... cb1e30910e Have pulse.el preserve existing overlay priorities # Conflicts: # etc/NEWS commit 72f87f88739befce2adf202749b7d651a8ef1551 Author: Alan Third Date: Sat Mar 7 14:39:05 2020 +0000 NS port documentation updates * doc/emacs/macos.texi (Mac / GNUstep Customization): Document some more of the ns- variables and remove incorrect font back-end information. * etc/NEWS: Update the documentation status of macOS news entries. diff --git a/doc/emacs/macos.texi b/doc/emacs/macos.texi index ae1b8d654f..00daa8b35d 100644 --- a/doc/emacs/macos.texi +++ b/doc/emacs/macos.texi @@ -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 diff --git a/etc/NEWS b/etc/NEWS index cfa946f2b1..1eff926114 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -3649,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 @@ -3708,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. commit 5b19db98adcfccf432ac40ccdad831723a4c1c06 Author: João Távora Date: Sat Mar 7 13:47:07 2020 +0000 ; * etc/NEWS: correctly describe what fido-mode is diff --git a/etc/NEWS b/etc/NEWS index e576bc11d5..cfa946f2b1 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1497,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 commit fc47e3ad99170649de5f318ab9c6aa06cd353af1 Author: João Távora Date: Sat Mar 7 13:10:07 2020 +0000 Let fido-mode users force a minibuffer-exit * lisp/icomplete.el (icomplete-fido-exit): Add FORCE arg. Rewrite docstring. (bug#38992) diff --git a/lisp/icomplete.el b/lisp/icomplete.el index 0a655d1e9e..66bc731f67 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el @@ -284,10 +284,14 @@ require user confirmation." (t (icomplete-force-complete-and-exit))))) -(defun icomplete-fido-exit () - "Exit minibuffer properly honoring the REQUIRE-MATCH argument." - (interactive) - (if minibuffer--require-match +(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))) commit e734961d4cb8f67ab677b97b9bb70c5e2e2cfb6d Author: Dmitry Gutov Date: Thu Mar 5 01:58:32 2020 +0200 icomplete-fido-exit: New command for the M-j binding * lisp/icomplete.el (icomplete-fido-exit): New command. (icomplete-fido-mode-map): Use it (bug#38992). diff --git a/lisp/icomplete.el b/lisp/icomplete.el index efe64d855a..0a655d1e9e 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el @@ -284,6 +284,13 @@ require user confirmation." (t (icomplete-force-complete-and-exit))))) +(defun icomplete-fido-exit () + "Exit minibuffer properly honoring the REQUIRE-MATCH argument." + (interactive) + (if 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 +306,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 "") 'icomplete-forward-completions) commit 335a9bd2157300266614a9ef5e5f106a10b3218a Author: Dmitry Gutov Date: Thu Mar 5 01:52:58 2020 +0200 minibuffer-force-complete-and-exit: Allow input with no matches * lisp/minibuffer.el (minibuffer--require-match): New variable. (completing-read-default): Bind it to the REQUIRE-MATCH value. (minibuffer-force-complete-and-exit): Consult it to allow input with no matches when a match is not required (bug#38992). * lisp/icomplete.el (icomplete-exhibit): Use it to render the correct parens around matches. diff --git a/lisp/icomplete.el b/lisp/icomplete.el index a1a67e2330..efe64d855a 100644 --- a/lisp/icomplete.el +++ b/lisp/icomplete.el @@ -541,7 +541,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. diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 49daabc44e..7f5b597542 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -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)) commit 34132d4bf663b1acc61c04e2b962339f75912f2d Author: Eli Zaretskii Date: Sat Mar 7 14:55:43 2020 +0200 ; * etc/NEWS: Mark 2 entries as fully documented. diff --git a/etc/NEWS b/etc/NEWS index ba1f657bcb..e576bc11d5 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -3108,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 @@ -3167,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" commit d28b73841b2233c9bdde5a24a7778bab2066e385 Author: Eli Zaretskii Date: Sat Mar 7 14:50:50 2020 +0200 ; * etc/NEWS: Fix the 'mml-secure-openpgp-sign-with-sender' entry. diff --git a/etc/NEWS b/etc/NEWS index f2472d6909..ba1f657bcb 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2209,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. commit d1d56a9fd9f7d44dc86947656f4c74f2ebc2e523 Author: Eli Zaretskii Date: Sat Mar 7 14:48:33 2020 +0200 ; * etc/NEWS: 'thunk-let' and 'thunk-let*' are fully documented. diff --git a/etc/NEWS b/etc/NEWS index b733b5b720..f2472d6909 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1985,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. commit fc4f4efabf13d61823514f99ba8da51de84e42c8 Author: Eli Zaretskii Date: Sat Mar 7 14:42:19 2020 +0200 ; * etc/NEWS: No need to document vc-hg and mergebase changes. diff --git a/etc/NEWS b/etc/NEWS index 9b952fa71f..b733b5b720 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1123,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. commit 9e8456cf0f6344619e6935ca6b59a7c75b1d62ee Author: Eli Zaretskii Date: Sat Mar 7 14:39:29 2020 +0200 ; * etc/NEWS: No need to document changes in Octave mode. diff --git a/etc/NEWS b/etc/NEWS index 75319253b2..9b952fa71f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -960,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. commit 25b4d6fa2863cf8759424bcc676f001179954b65 Author: Eli Zaretskii Date: Sat Mar 7 14:38:07 2020 +0200 ; * etc/NEWS: No need to document changes in map.el and seq.el. diff --git a/etc/NEWS b/etc/NEWS index 357d2ef806..75319253b2 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -888,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. @@ -899,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. commit fc4d0f86daef4d00a2a7f7a251adcf97de601eb5 Author: Eli Zaretskii Date: Sat Mar 7 14:33:16 2020 +0200 ; * etc/NEWS: No need to document Ido news. diff --git a/etc/NEWS b/etc/NEWS index e575140978..357d2ef806 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -857,6 +857,7 @@ 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. commit d4ac478cb39548bd0af360c94505b0a385180acc Author: Eli Zaretskii Date: Sat Mar 7 14:32:06 2020 +0200 ; * etc/NEWS: No need to document news of doc-view.el. diff --git a/etc/NEWS b/etc/NEWS index 6b2de77f1b..e575140978 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -845,10 +845,13 @@ 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. commit 08c042bd26f9a194a25aef241f8747ce47ac2798 Author: Eli Zaretskii Date: Sat Mar 7 14:23:23 2020 +0200 Document that 'byte-compile-dynamic' is obsolete * doc/lispref/compile.texi (Dynamic Loading): Document that this is deprecated. * etc/NEWS: mark the 'byte-compile-dynamic' entry as documented. diff --git a/doc/lispref/compile.texi b/doc/lispref/compile.texi index 311b6f5b3f..e979fda41e 100644 --- a/doc/lispref/compile.texi +++ b/doc/lispref/compile.texi @@ -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 diff --git a/etc/NEWS b/etc/NEWS index 0239476806..6b2de77f1b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -803,10 +803,11 @@ You can use this new user option to control indentation of arguments of ** 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 commit 512b66abd7437d908fae781c312e141bdaeed90c Author: Eli Zaretskii Date: Sat Mar 7 14:10:14 2020 +0200 ; * etc/NEWS: No need to document 'goto-address-uri-schemes-ignored'. diff --git a/etc/NEWS b/etc/NEWS index fcf9dbf0fe..0239476806 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -789,6 +789,7 @@ This command can now output wiki and mediawiki format tables. ** 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. commit 3103c01c3e41fe37afed908e9982a98ff9d31c94 Author: Eli Zaretskii Date: Sat Mar 7 14:05:52 2020 +0200 ; * etc/NEWS: Formatting fixes. diff --git a/etc/NEWS b/etc/NEWS index 1936b25213..fcf9dbf0fe 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -759,20 +759,21 @@ 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 @@ -781,9 +782,9 @@ an offset to absolute line numbers. *** '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 @@ -792,9 +793,9 @@ This command can now output wiki and mediawiki format tables. 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. @@ -1819,7 +1820,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 @@ -2650,6 +2650,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 commit 98306fdfb8a59dc9ff6a077a00281ca02b2e5ba7 Author: Eli Zaretskii Date: Sat Mar 7 13:55:37 2020 +0200 ; * etc/NEWS: No need to document deprecation of 'cl'. diff --git a/etc/NEWS b/etc/NEWS index cf0252c0fd..1936b25213 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -750,6 +750,7 @@ 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'. --- commit 6281ed58bec81ab6cd4804aee866384b1aeb2468 Author: Eli Zaretskii Date: Sat Mar 7 13:54:03 2020 +0200 ; * etc/NEWS: No need to document the change in 'list-processes'. diff --git a/etc/NEWS b/etc/NEWS index 1d5634890a..cf0252c0fd 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -746,6 +746,7 @@ 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). commit e252341e114364b0e2d5326841fe8a77b182a869 Author: Eli Zaretskii Date: Sat Mar 7 13:48:06 2020 +0200 ; * etc/NEWS: 'backup-by-copying-when-privileged-mismatch' is documented. diff --git a/etc/NEWS b/etc/NEWS index f52c04012b..1d5634890a 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -592,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'; commit ec5a267ddc0532a192604664ba6bd8f9021b4a8c Author: Eli Zaretskii Date: Sat Mar 7 13:46:06 2020 +0200 ; * etc/NEWS: Mark 'byte-count-to-string-function' as undocumented. diff --git a/etc/NEWS b/etc/NEWS index b960c336b3..f52c04012b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -560,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. commit 89307ebccd709a75e2bdc6858efcfdcfe9d7bda2 Author: Eli Zaretskii Date: Sat Mar 7 13:42:35 2020 +0200 ; * etc/NEWS: Mark 'completion-common-part' face entry as not documented. diff --git a/etc/NEWS b/etc/NEWS index 08bd2af159..b960c336b3 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -493,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. +++ commit fdbe7cacfb1e56e8a2115971ad2a09cdd1b0fd85 Author: Eli Zaretskii Date: Sat Mar 7 13:40:10 2020 +0200 Document the changes in 'read-answer' * doc/lispref/minibuf.texi (Multiple Queries): Document the fact that 'read-answer' can now accept non-character input events. diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index 1266cf8ef6..c1615993f5 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -2227,16 +2227,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 diff --git a/etc/NEWS b/etc/NEWS index 2d719fb7a5..08bd2af159 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -347,6 +347,7 @@ 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'. commit 10c58356e4e7ab1bae9b5fe1c1304e1f8dc82f83 Author: Eli Zaretskii Date: Sat Mar 7 13:32:52 2020 +0200 Document changes in lexical-binding * doc/lispref/variables.texi (Using Lexical Binding): Document that lexical-binding is now turned on by default in more cases. * etc/NEWS: Fix wording of the NEWS entry about the above, and mark it as fully documented. diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi index 33897bb633..abcd4bbd0f 100644 --- a/doc/lispref/variables.texi +++ b/doc/lispref/variables.texi @@ -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 diff --git a/etc/NEWS b/etc/NEWS index 3332143dc2..2d719fb7a5 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -351,10 +351,13 @@ The default value is 30000, as the previously hard-coded threshold. 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 commit 5cb312b5b913540ab3dcedbfef7acfc58da50c41 Author: Amin Bandali Date: Fri Mar 6 12:54:23 2020 -0500 Update ERC mailing list address * lisp/erc/erc.el (erc-official-location): As part of bringing ERC under the Emacs umbrella, erc-discuss has been renamed to emacs-erc, and will be *the* mailing list for discussions and announcements about ERC going forward. The other two lists, erc-announce and erc-commit, are now retired. For more details, see the announcement at . diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index a46755153e..81325df3f4 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -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 commit cb1877321b8a04cdb9b890d76d99a9f5a7ed5bce Author: Roland Winkler Date: Fri Mar 6 09:37:55 2020 +0100 Use regexp-opt to define bibtex-autokey-transcriptions. (Bug#39686) diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el index a7be57e5a3..670e763814 100644 --- a/lisp/textmodes/bibtex.el +++ b/lisp/textmodes/bibtex.el @@ -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 commit 3f9c340de04d7572b02ef1a4c3793420d29a768c Author: Eli Zaretskii Date: Fri Mar 6 10:14:42 2020 +0200 Improve documentation of 'table-generate-source' * lisp/textmodes/table.el (table-generate-source): Doc fix. (Bug#39935) * etc/NEWS: Fix wording of the 'table-generate-source' entry and mark it as documented. diff --git a/etc/NEWS b/etc/NEWS index 8d0e0b6759..3332143dc2 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -768,8 +768,9 @@ an offset to absolute line numbers. ** 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 diff --git a/lisp/textmodes/table.el b/lisp/textmodes/table.el index 4482e7d4d2..bd2cac7aeb 100644 --- a/lisp/textmodes/table.el +++ b/lisp/textmodes/table.el @@ -2912,16 +2912,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: commit 33b31dc314cf71f3b1569f25756d69c6915168ff Author: Eli Zaretskii Date: Fri Mar 6 09:48:10 2020 +0200 Attempt to avoid rare segfaults in show_mouse_face * src/xdisp.c (show_mouse_face): Don't display the active region if called on a frame different from the one recorded in HLINFO. (Bug#37671) diff --git a/src/xdisp.c b/src/xdisp.c index 3a8b5e3f1d..a4de2698ca 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -31454,6 +31454,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 commit 88c6db91961945e4ede53d66216c2484f0c5342b Author: Eli Zaretskii Date: Thu Mar 5 17:57:21 2020 +0200 Avoid crashes when a fontset has strange entries * src/fontset.c (reorder_font_vector): Skip nil entries in the loop that assigns scores to rfont_def's. (fontset_compare_rfontdef): Cope with nil. This has the effect of moving any nil entries to the end of the font-group, and avoids crashing if an element other than the last in the font-group is nil. (Bug#39892) diff --git a/src/fontset.c b/src/fontset.c index bca9452418..c2bb8b21f2 100644 --- a/src/fontset.c +++ b/src/fontset.c @@ -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; commit 1814c7e158685045278f991de5eba4e40e8c8199 Author: Mattias Engdegård Date: Thu Mar 5 12:49:26 2020 +0100 Fix rx error with ? and ?? The ? and ?? rx operators are special in that they can be written as characters (space and '?' respectively). This confused the definition look-up mechanism in rare cases. * lisp/emacs-lisp/rx.el (rx--expand-def): Don't look up non-symbols. * test/lisp/emacs-lisp/rx-tests.el (rx-charset-or): Test. diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index d4a9171027..aa4b2addd4 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -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 diff --git a/test/lisp/emacs-lisp/rx-tests.el b/test/lisp/emacs-lisp/rx-tests.el index 4888e1d9d1..0fece4004b 100644 --- a/test/lisp/emacs-lisp/rx-tests.el +++ b/test/lisp/emacs-lisp/rx-tests.el @@ -316,7 +316,9 @@ (should (equal (rx (not (or (in "abc") (char "bcd")))) "[^a-d]")) (should (equal (rx (or (not (in "abc")) (not (char "bcd")))) - "[^bc]"))) + "[^bc]")) + (should (equal (rx (or "x" (? "yz"))) + "x\\|\\(?:yz\\)?"))) (ert-deftest rx-def-in-charset-or () (rx-let ((a (any "badc")) commit 40fb20061e6b9b2b22aeee5b7e9f038dc9ba843b Author: Mattias Engdegård Date: Thu Mar 5 12:10:51 2020 +0100 * lisp/emacs-lisp/rx.el (rx--string-to-intervals): Fix error string. diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index a0b2444346..d4a9171027 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -360,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. commit 08d7d28d35aa0c755d6f77b382592ba31552adc2 Author: Justin Burkett Date: Thu Mar 5 09:10:03 2020 +0100 Fix args in 'window-text-pixel-size' call in 'fit-window-to-buffer' * lisp/window.el (fit-window-to-buffer): Fix arguments in 'window-text-pixel-size' call. Copyright-paperwork-exempt: yes diff --git a/lisp/window.el b/lisp/window.el index ceab43f7cd..5c4ff83d82 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -9113,8 +9113,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 commit cb1e30910ea7972ea82e28545782c75496d7b6d3 Author: João Távora Date: Fri Feb 28 13:30:48 2020 +0000 Have pulse.el preserve existing overlay priorities Fixes: bug#39821 * lisp/cedet/pulse.el (pulse-momentary-highlight-overlay): Save overlay priority. (pulse-momentary-unhighlight): Restore. diff --git a/lisp/cedet/pulse.el b/lisp/cedet/pulse.el index 5713a7b0d1..16243e16b4 100644 --- a/lisp/cedet/pulse.el +++ b/lisp/cedet/pulse.el @@ -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)))