aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2023-05-17 09:16:48 +0800
committerPo Lu2023-05-17 09:16:48 +0800
commitbb95cdaa0693ecea2953d14f2808a23b66ac9446 (patch)
tree0baff93b05b3d75ce7cec9f491ea7c687942adb5
parentbb8bf9203ed33de0bb269c8ff69067aa7b3a692a (diff)
parent6cb963b73c3768958e13e96b2534d1e99239a3ff (diff)
downloademacs-bb95cdaa0693ecea2953d14f2808a23b66ac9446.tar.gz
emacs-bb95cdaa0693ecea2953d14f2808a23b66ac9446.zip
Merge remote-tracking branch 'origin/master' into feature/android
-rw-r--r--doc/emacs/package.texi11
-rw-r--r--doc/misc/use-package.texi50
-rw-r--r--etc/NEWS11
-rw-r--r--lib/file-has-acl.c37
-rw-r--r--lib/gettime.c4
-rw-r--r--lib/gettimeofday.c14
-rw-r--r--lib/nanosleep.c3
-rw-r--r--lib/pselect.c6
-rw-r--r--lib/stat-time.h33
-rw-r--r--lib/timespec.h5
-rw-r--r--lib/utimens.c20
-rw-r--r--lisp/emacs-lisp/package-vc.el40
-rw-r--r--lisp/progmodes/eglot.el42
-rw-r--r--lisp/use-package/use-package-core.el111
-rw-r--r--lisp/use-package/use-package-ensure.el3
-rw-r--r--lisp/windmove.el2
-rw-r--r--m4/gnulib-common.m46
-rw-r--r--test/lisp/net/tramp-tests.el12
-rw-r--r--test/lisp/use-package/use-package-tests.el54
19 files changed, 380 insertions, 84 deletions
diff --git a/doc/emacs/package.texi b/doc/emacs/package.texi
index 6722185cb20..1229557673d 100644
--- a/doc/emacs/package.texi
+++ b/doc/emacs/package.texi
@@ -682,6 +682,17 @@ A string providing the repository-relative name of the documentation
682file from which to build an Info file. This can be a Texinfo file or 682file from which to build an Info file. This can be a Texinfo file or
683an Org file. 683an Org file.
684 684
685@item :make
686A string or list of strings providing the target or targets defined in
687the repository Makefile which should run before building the Info
688file. Only takes effect when @code{package-vc-allow-side-effects} is
689non-nil.
690
691@item :shell-command
692A string providing the shell command to run before building the Info
693file. Only takes effect when @code{package-vc-allow-side-effects} is
694non-@code{nil}.
695
685@item :vc-backend 696@item :vc-backend
686A symbol naming the VC backend to use for downloading a copy of the 697A symbol naming the VC backend to use for downloading a copy of the
687package's repository (@pxref{Version Control Systems,,,emacs, The GNU 698package's repository (@pxref{Version Control Systems,,,emacs, The GNU
diff --git a/doc/misc/use-package.texi b/doc/misc/use-package.texi
index 87105c4db00..d75cb67e089 100644
--- a/doc/misc/use-package.texi
+++ b/doc/misc/use-package.texi
@@ -1554,8 +1554,11 @@ The standard Emacs package manager is documented in the Emacs manual
1554(@pxref{Package Installation,,, emacs, GNU Emacs Manual}). The 1554(@pxref{Package Installation,,, emacs, GNU Emacs Manual}). The
1555@code{use-package} macro provides the @code{:ensure} and @code{:pin} 1555@code{use-package} macro provides the @code{:ensure} and @code{:pin}
1556keywords that interface with that package manager to automatically 1556keywords that interface with that package manager to automatically
1557install packages. This is particularly useful if you use your init 1557install packages. The @code{:vc} keyword may be used to control how
1558file on more than one system. 1558package sources are downloaded; e.g., from remote hosts
1559(@pxref{Fetching Package Sources,,, emacs, GNU Emacs Manual}). This
1560is particularly useful if you use your init file on more than one
1561system.
1559 1562
1560@menu 1563@menu
1561* Install package:: 1564* Install package::
@@ -1607,6 +1610,49 @@ packages:
1607You can override the above setting for a single package by adding 1610You can override the above setting for a single package by adding
1608@w{@code{:ensure nil}} to its declaration. 1611@w{@code{:ensure nil}} to its declaration.
1609 1612
1613@findex :vc
1614The @code{:vc} keyword can be used to control how packages are
1615downloaded and/or installed. More specifically, it allows one to fetch
1616and update packages directly from a version control system. This is
1617especially convenient when wanting to install a package that is not on
1618any package archive.
1619
1620The keyword accepts the same arguments as specified in
1621@pxref{Fetching Package Sources,,, emacs, GNU Emacs Manual}, except
1622that a name need not explicitly be given: it is inferred from the
1623declaration. The accepted property list is augmented by a @code{:rev}
1624keyword, which has the same shape as the @code{REV} argument to
1625@code{package-vc-install}. Notably -- even when not specified --
1626@code{:rev} defaults to checking out the last release of the package.
1627You can use @code{:rev :newest} to check out the latest commit.
1628
1629For example,
1630
1631@example
1632@group
1633(use-package bbdb
1634 :vc (:url "https://git.savannah.nongnu.org/git/bbdb.git"
1635 :rev :newest))
1636@end group
1637@end example
1638
1639would try -- by invoking @code{package-vc-install} -- to install the
1640latest commit of the package @code{foo} from the specified remote.
1641
1642This can also be used for local packages, by combining it with the
1643@code{:load-path} (@pxref{Load path}) keyword:
1644
1645@example
1646@group
1647;; Use a local copy of BBDB instead of the one from GNU ELPA.
1648(use-package bbdb
1649 :vc t
1650 :load-path "/path/to/bbdb/dir/")
1651@end group
1652@end example
1653
1654The above dispatches to @code{package-vc-install-from-checkout}.
1655
1610@node Pinning packages 1656@node Pinning packages
1611@section Pinning packages using @code{:pin} 1657@section Pinning packages using @code{:pin}
1612@cindex installing package from specific archive 1658@cindex installing package from specific archive
diff --git a/etc/NEWS b/etc/NEWS
index a342614a9ef..d16eee547de 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -312,6 +312,11 @@ When non-nil, it will automatically register every package as a
312project, that you can quickly select using 'project-switch-project' 312project, that you can quickly select using 'project-switch-project'
313('C-x p p'). 313('C-x p p').
314 314
315---
316*** New user option 'package-vc-allow-side-effects'.
317When non-nil, package specifications with side-effects for building
318software will used when building a package.
319
315** Flymake 320** Flymake
316 321
317+++ 322+++
@@ -340,6 +345,12 @@ instead of:
340 and another_expression): 345 and another_expression):
341 do_something() 346 do_something()
342 347
348** use-package
349
350+++
351*** New ':vc' keyword.
352This keyword enables the user to install packages using 'package-vc'.
353
343 354
344* New Modes and Packages in Emacs 30.1 355* New Modes and Packages in Emacs 30.1
345 356
diff --git a/lib/file-has-acl.c b/lib/file-has-acl.c
index 38bc806dc49..4cddc80bd13 100644
--- a/lib/file-has-acl.c
+++ b/lib/file-has-acl.c
@@ -29,7 +29,10 @@
29 29
30#include "acl-internal.h" 30#include "acl-internal.h"
31 31
32#include "minmax.h"
33
32#if USE_ACL && HAVE_LINUX_XATTR_H && HAVE_LISTXATTR 34#if USE_ACL && HAVE_LINUX_XATTR_H && HAVE_LISTXATTR
35# include <stdckdint.h>
33# include <string.h> 36# include <string.h>
34# include <arpa/inet.h> 37# include <arpa/inet.h>
35# include <sys/xattr.h> 38# include <sys/xattr.h>
@@ -181,32 +184,44 @@ file_has_acl (char const *name, struct stat const *sb)
181 && errno == ERANGE) 184 && errno == ERANGE)
182 { 185 {
183 free (heapbuf); 186 free (heapbuf);
184 listbufsize = listxattr (name, NULL, 0); 187 ssize_t newsize = listxattr (name, NULL, 0);
185 if (listbufsize < 0) 188 if (newsize <= 0)
186 return -1; 189 return newsize;
187 if (SIZE_MAX < listbufsize) 190
191 /* Grow LISTBUFSIZE to at least NEWSIZE. Grow it by a
192 nontrivial amount too, to defend against denial of
193 service by an adversary that fiddles with ACLs. */
194 bool overflow = ckd_add (&listbufsize, listbufsize, listbufsize >> 1);
195 listbufsize = MAX (listbufsize, newsize);
196 if (overflow || SIZE_MAX < listbufsize)
188 { 197 {
189 errno = ENOMEM; 198 errno = ENOMEM;
190 return -1; 199 return -1;
191 } 200 }
201
192 listbuf = heapbuf = malloc (listbufsize); 202 listbuf = heapbuf = malloc (listbufsize);
193 if (!listbuf) 203 if (!listbuf)
194 return -1; 204 return -1;
195 } 205 }
196 206
207 /* In Fedora 39, a file can have both NFSv4 and POSIX ACLs,
208 but if it has an NFSv4 ACL that's the one that matters.
209 In earlier Fedora the two types of ACLs were mutually exclusive.
210 Attempt to work correctly on both kinds of systems. */
211 bool nfsv4_acl
212 = 0 < listsize && have_xattr (XATTR_NAME_NFSV4_ACL, listbuf, listsize);
197 int ret 213 int ret
198 = (listsize < 0 ? -1 214 = (listsize <= 0 ? listsize
199 : (have_xattr (XATTR_NAME_POSIX_ACL_ACCESS, listbuf, listsize) 215 : (nfsv4_acl
216 || have_xattr (XATTR_NAME_POSIX_ACL_ACCESS, listbuf, listsize)
200 || (S_ISDIR (sb->st_mode) 217 || (S_ISDIR (sb->st_mode)
201 && have_xattr (XATTR_NAME_POSIX_ACL_DEFAULT, 218 && have_xattr (XATTR_NAME_POSIX_ACL_DEFAULT,
202 listbuf, listsize)))); 219 listbuf, listsize))));
203 bool nfsv4_acl_but_no_posix_acl
204 = ret == 0 && have_xattr (XATTR_NAME_NFSV4_ACL, listbuf, listsize);
205 free (heapbuf); 220 free (heapbuf);
206 221
207 /* If there is an NFSv4 ACL but no POSIX ACL, follow up with a 222 /* If there is an NFSv4 ACL, follow up with a getxattr syscall
208 getxattr syscall to see whether the NFSv4 ACL is nontrivial. */ 223 to see whether the NFSv4 ACL is nontrivial. */
209 if (nfsv4_acl_but_no_posix_acl) 224 if (nfsv4_acl)
210 { 225 {
211 ret = getxattr (name, XATTR_NAME_NFSV4_ACL, 226 ret = getxattr (name, XATTR_NAME_NFSV4_ACL,
212 stackbuf.xattr, sizeof stackbuf.xattr); 227 stackbuf.xattr, sizeof stackbuf.xattr);
diff --git a/lib/gettime.c b/lib/gettime.c
index f86cc4efbff..ec40ff903e1 100644
--- a/lib/gettime.c
+++ b/lib/gettime.c
@@ -35,8 +35,8 @@ gettime (struct timespec *ts)
35#else 35#else
36 struct timeval tv; 36 struct timeval tv;
37 gettimeofday (&tv, NULL); 37 gettimeofday (&tv, NULL);
38 ts->tv_sec = tv.tv_sec; 38 *ts = (struct timespec) { .tv_sec = tv.tv_sec,
39 ts->tv_nsec = tv.tv_usec * 1000; 39 .tv_nsec = tv.tv_usec * 1000 };
40#endif 40#endif
41} 41}
42 42
diff --git a/lib/gettimeofday.c b/lib/gettimeofday.c
index d896ec132b9..c71629cbc57 100644
--- a/lib/gettimeofday.c
+++ b/lib/gettimeofday.c
@@ -113,8 +113,10 @@ gettimeofday (struct timeval *restrict tv, void *restrict tz)
113 ULONGLONG since_1970 = 113 ULONGLONG since_1970 =
114 since_1601 - (ULONGLONG) 134774 * (ULONGLONG) 86400 * (ULONGLONG) 10000000; 114 since_1601 - (ULONGLONG) 134774 * (ULONGLONG) 86400 * (ULONGLONG) 10000000;
115 ULONGLONG microseconds_since_1970 = since_1970 / (ULONGLONG) 10; 115 ULONGLONG microseconds_since_1970 = since_1970 / (ULONGLONG) 10;
116 tv->tv_sec = microseconds_since_1970 / (ULONGLONG) 1000000; 116 *tv = (struct timeval) {
117 tv->tv_usec = microseconds_since_1970 % (ULONGLONG) 1000000; 117 .tv_sec = microseconds_since_1970 / (ULONGLONG) 1000000,
118 .tv_usec = microseconds_since_1970 % (ULONGLONG) 1000000
119 };
118 120
119 return 0; 121 return 0;
120 122
@@ -127,10 +129,7 @@ gettimeofday (struct timeval *restrict tv, void *restrict tz)
127 struct timeval otv; 129 struct timeval otv;
128 int result = gettimeofday (&otv, (struct timezone *) tz); 130 int result = gettimeofday (&otv, (struct timezone *) tz);
129 if (result == 0) 131 if (result == 0)
130 { 132 *tv = otv;
131 tv->tv_sec = otv.tv_sec;
132 tv->tv_usec = otv.tv_usec;
133 }
134# else 133# else
135 int result = gettimeofday (tv, (struct timezone *) tz); 134 int result = gettimeofday (tv, (struct timezone *) tz);
136# endif 135# endif
@@ -143,8 +142,7 @@ gettimeofday (struct timeval *restrict tv, void *restrict tz)
143# error "Only 1-second nominal clock resolution found. Is that intended?" \ 142# error "Only 1-second nominal clock resolution found. Is that intended?" \
144 "If so, compile with the -DOK_TO_USE_1S_CLOCK option." 143 "If so, compile with the -DOK_TO_USE_1S_CLOCK option."
145# endif 144# endif
146 tv->tv_sec = time (NULL); 145 *tv = (struct timeval) { .tv_sec = time (NULL), .tv_usec = 0 };
147 tv->tv_usec = 0;
148 146
149 return 0; 147 return 0;
150 148
diff --git a/lib/nanosleep.c b/lib/nanosleep.c
index 3f295f49b5d..10974df461e 100644
--- a/lib/nanosleep.c
+++ b/lib/nanosleep.c
@@ -60,8 +60,7 @@ nanosleep (const struct timespec *requested_delay,
60 static_assert (TYPE_MAXIMUM (time_t) / 24 / 24 / 60 / 60); 60 static_assert (TYPE_MAXIMUM (time_t) / 24 / 24 / 60 / 60);
61 const time_t limit = 24 * 24 * 60 * 60; 61 const time_t limit = 24 * 24 * 60 * 60;
62 time_t seconds = requested_delay->tv_sec; 62 time_t seconds = requested_delay->tv_sec;
63 struct timespec intermediate; 63 struct timespec intermediate = *requested_delay;
64 intermediate.tv_nsec = requested_delay->tv_nsec;
65 64
66 while (limit < seconds) 65 while (limit < seconds)
67 { 66 {
diff --git a/lib/pselect.c b/lib/pselect.c
index 52d38378783..1b8c19130c2 100644
--- a/lib/pselect.c
+++ b/lib/pselect.c
@@ -59,8 +59,10 @@ pselect (int nfds, fd_set *restrict rfds,
59 return -1; 59 return -1;
60 } 60 }
61 61
62 tv.tv_sec = timeout->tv_sec; 62 tv = (struct timeval) {
63 tv.tv_usec = (timeout->tv_nsec + 999) / 1000; 63 .tv_sec = timeout->tv_sec,
64 .tv_usec = (timeout->tv_nsec + 999) / 1000
65 };
64 tvp = &tv; 66 tvp = &tv;
65 } 67 }
66 else 68 else
diff --git a/lib/stat-time.h b/lib/stat-time.h
index 5b2702356ee..af084102dae 100644
--- a/lib/stat-time.h
+++ b/lib/stat-time.h
@@ -122,10 +122,8 @@ get_stat_atime (struct stat const *st)
122#ifdef STAT_TIMESPEC 122#ifdef STAT_TIMESPEC
123 return STAT_TIMESPEC (st, st_atim); 123 return STAT_TIMESPEC (st, st_atim);
124#else 124#else
125 struct timespec t; 125 return (struct timespec) { .tv_sec = st->st_atime,
126 t.tv_sec = st->st_atime; 126 .tv_nsec = get_stat_atime_ns (st) };
127 t.tv_nsec = get_stat_atime_ns (st);
128 return t;
129#endif 127#endif
130} 128}
131 129
@@ -136,10 +134,8 @@ get_stat_ctime (struct stat const *st)
136#ifdef STAT_TIMESPEC 134#ifdef STAT_TIMESPEC
137 return STAT_TIMESPEC (st, st_ctim); 135 return STAT_TIMESPEC (st, st_ctim);
138#else 136#else
139 struct timespec t; 137 return (struct timespec) { .tv_sec = st->st_ctime,
140 t.tv_sec = st->st_ctime; 138 .tv_nsec = get_stat_ctime_ns (st) };
141 t.tv_nsec = get_stat_ctime_ns (st);
142 return t;
143#endif 139#endif
144} 140}
145 141
@@ -150,10 +146,8 @@ get_stat_mtime (struct stat const *st)
150#ifdef STAT_TIMESPEC 146#ifdef STAT_TIMESPEC
151 return STAT_TIMESPEC (st, st_mtim); 147 return STAT_TIMESPEC (st, st_mtim);
152#else 148#else
153 struct timespec t; 149 return (struct timespec) { .tv_sec = st->st_mtime,
154 t.tv_sec = st->st_mtime; 150 .tv_nsec = get_stat_mtime_ns (st) };
155 t.tv_nsec = get_stat_mtime_ns (st);
156 return t;
157#endif 151#endif
158} 152}
159 153
@@ -168,8 +162,8 @@ get_stat_birthtime (_GL_UNUSED struct stat const *st)
168 || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC) 162 || defined HAVE_STRUCT_STAT_ST_BIRTHTIM_TV_NSEC)
169 t = STAT_TIMESPEC (st, st_birthtim); 163 t = STAT_TIMESPEC (st, st_birthtim);
170#elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC 164#elif defined HAVE_STRUCT_STAT_ST_BIRTHTIMENSEC
171 t.tv_sec = st->st_birthtime; 165 t = (struct timespec) { .tv_sec = st->st_birthtime,
172 t.tv_nsec = st->st_birthtimensec; 166 .tv_nsec = st->st_birthtimensec };
173#elif defined _WIN32 && ! defined __CYGWIN__ 167#elif defined _WIN32 && ! defined __CYGWIN__
174 /* Native Windows platforms (but not Cygwin) put the "file creation 168 /* Native Windows platforms (but not Cygwin) put the "file creation
175 time" in st_ctime (!). See 169 time" in st_ctime (!). See
@@ -177,13 +171,11 @@ get_stat_birthtime (_GL_UNUSED struct stat const *st)
177# if _GL_WINDOWS_STAT_TIMESPEC 171# if _GL_WINDOWS_STAT_TIMESPEC
178 t = st->st_ctim; 172 t = st->st_ctim;
179# else 173# else
180 t.tv_sec = st->st_ctime; 174 t = (struct timespec) { .tv_sec = st->st_ctime };
181 t.tv_nsec = 0;
182# endif 175# endif
183#else 176#else
184 /* Birth time is not supported. */ 177 /* Birth time is not supported. */
185 t.tv_sec = -1; 178 t = (struct timespec) { .tv_sec = -1, .tv_nsec = -1 };
186 t.tv_nsec = -1;
187#endif 179#endif
188 180
189#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \ 181#if (defined HAVE_STRUCT_STAT_ST_BIRTHTIMESPEC_TV_NSEC \
@@ -195,10 +187,7 @@ get_stat_birthtime (_GL_UNUSED struct stat const *st)
195 sometimes returns junk in the birth time fields; work around this 187 sometimes returns junk in the birth time fields; work around this
196 bug if it is detected. */ 188 bug if it is detected. */
197 if (! (t.tv_sec && 0 <= t.tv_nsec && t.tv_nsec < 1000000000)) 189 if (! (t.tv_sec && 0 <= t.tv_nsec && t.tv_nsec < 1000000000))
198 { 190 t = (struct timespec) { .tv_sec = -1, .tv_nsec = -1 };
199 t.tv_sec = -1;
200 t.tv_nsec = -1;
201 }
202#endif 191#endif
203 192
204 return t; 193 return t;
diff --git a/lib/timespec.h b/lib/timespec.h
index 0bdfd76ef78..e94da75defe 100644
--- a/lib/timespec.h
+++ b/lib/timespec.h
@@ -55,10 +55,7 @@ enum { LOG10_TIMESPEC_RESOLUTION = LOG10_TIMESPEC_HZ };
55_GL_TIMESPEC_INLINE struct timespec 55_GL_TIMESPEC_INLINE struct timespec
56make_timespec (time_t s, long int ns) 56make_timespec (time_t s, long int ns)
57{ 57{
58 struct timespec r; 58 return (struct timespec) { .tv_sec = s, .tv_nsec = ns };
59 r.tv_sec = s;
60 r.tv_nsec = ns;
61 return r;
62} 59}
63 60
64/* Return negative, zero, positive if A < B, A == B, A > B, respectively. */ 61/* Return negative, zero, positive if A < B, A == B, A > B, respectively. */
diff --git a/lib/utimens.c b/lib/utimens.c
index 4c5377eca0f..faa197e6cb5 100644
--- a/lib/utimens.c
+++ b/lib/utimens.c
@@ -405,10 +405,10 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2])
405 struct timeval *t; 405 struct timeval *t;
406 if (ts) 406 if (ts)
407 { 407 {
408 timeval[0].tv_sec = ts[0].tv_sec; 408 timeval[0] = (struct timeval) { .tv_sec = ts[0].tv_sec,
409 timeval[0].tv_usec = ts[0].tv_nsec / 1000; 409 .tv_usec = ts[0].tv_nsec / 1000 };
410 timeval[1].tv_sec = ts[1].tv_sec; 410 timeval[1] = (struct timeval) { .tv_sec = ts[1].tv_sec,
411 timeval[1].tv_usec = ts[1].tv_nsec / 1000; 411 .tv_usec = ts[1].tv_nsec / 1000 };
412 t = timeval; 412 t = timeval;
413 } 413 }
414 else 414 else
@@ -502,8 +502,8 @@ fdutimens (int fd, char const *file, struct timespec const timespec[2])
502 struct utimbuf *ut; 502 struct utimbuf *ut;
503 if (ts) 503 if (ts)
504 { 504 {
505 utimbuf.actime = ts[0].tv_sec; 505 utimbuf = (struct utimbuf) { .actime = ts[0].tv_sec,
506 utimbuf.modtime = ts[1].tv_sec; 506 .modtime = ts[1].tv_sec };
507 ut = &utimbuf; 507 ut = &utimbuf;
508 } 508 }
509 else 509 else
@@ -621,10 +621,10 @@ lutimens (char const *file, struct timespec const timespec[2])
621 int result; 621 int result;
622 if (ts) 622 if (ts)
623 { 623 {
624 timeval[0].tv_sec = ts[0].tv_sec; 624 timeval[0] = (struct timeval) { .tv_sec = ts[0].tv_sec,
625 timeval[0].tv_usec = ts[0].tv_nsec / 1000; 625 .tv_usec = ts[0].tv_nsec / 1000 };
626 timeval[1].tv_sec = ts[1].tv_sec; 626 timeval[1] = (struct timeval) { .tv_sec = ts[1].tv_sec,
627 timeval[1].tv_usec = ts[1].tv_nsec / 1000; 627 .tv_usec = ts[1].tv_nsec / 1000 };
628 t = timeval; 628 t = timeval;
629 } 629 }
630 else 630 else
diff --git a/lisp/emacs-lisp/package-vc.el b/lisp/emacs-lisp/package-vc.el
index beca0bd00e2..35acd493b36 100644
--- a/lisp/emacs-lisp/package-vc.el
+++ b/lisp/emacs-lisp/package-vc.el
@@ -344,6 +344,40 @@ asynchronously."
344 "\n") 344 "\n")
345 nil pkg-file nil 'silent)))) 345 nil pkg-file nil 'silent))))
346 346
347(defcustom package-vc-allow-side-effects nil
348 "Whether to process :make and :shell-command spec arguments.
349
350It may be necessary to run :make and :shell-command arguments in
351order to initialize a package or build its documentation, but
352please be careful when changing this option, as installing and
353updating a package can run potentially harmful code.
354
355When set to a list of symbols (packages), run commands for only
356packages in the list. When nil, never run commands. Otherwise
357when non-nil, run commands for any package with :make or
358:shell-command specified.
359
360Package specs are loaded from trusted package archives."
361 :type '(choice (const :tag "Run for all packages" t)
362 (repeat :tag "Run only for selected packages" (symbol :tag "Package name"))
363 (const :tag "Never run" nil))
364 :version "30.1")
365
366(defun package-vc--make (pkg-spec pkg-desc)
367 "Process :make and :shell-command in PKG-SPEC.
368PKG-DESC is the package descriptor for the package that is being
369prepared."
370 (let ((target (plist-get pkg-spec :make))
371 (cmd (plist-get pkg-spec :shell-command))
372 (buf (format " *package-vc make %s*" (package-desc-name pkg-desc))))
373 (when (or cmd target)
374 (with-current-buffer (get-buffer-create buf)
375 (erase-buffer)
376 (when (and cmd (/= 0 (call-process shell-file-name nil t nil shell-command-switch cmd)))
377 (warn "Failed to run %s, see buffer %S" cmd (buffer-name)))
378 (when (and target (/= 0 (apply #'call-process "make" nil t nil (if (consp target) target (list target)))))
379 (warn "Failed to make %s, see buffer %S" target (buffer-name)))))))
380
347(declare-function org-export-to-file "ox" (backend file)) 381(declare-function org-export-to-file "ox" (backend file))
348 382
349(defun package-vc--build-documentation (pkg-desc file) 383(defun package-vc--build-documentation (pkg-desc file)
@@ -486,6 +520,12 @@ documentation and marking the package as installed."
486 ;; Generate package file 520 ;; Generate package file
487 (package-vc--generate-description-file pkg-desc pkg-file) 521 (package-vc--generate-description-file pkg-desc pkg-file)
488 522
523 ;; Process :make and :shell-command arguments before building documentation
524 (when (or (eq package-vc-allow-side-effects t)
525 (memq (package-desc-name pkg-desc)
526 package-vc-allow-side-effects))
527 (package-vc--make pkg-spec pkg-desc))
528
489 ;; Detect a manual 529 ;; Detect a manual
490 (when (executable-find "install-info") 530 (when (executable-find "install-info")
491 (dolist (doc-file (ensure-list (plist-get pkg-spec :doc))) 531 (dolist (doc-file (ensure-list (plist-get pkg-spec :doc)))
diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el
index 52f87c1af5d..a65795f1dfc 100644
--- a/lisp/progmodes/eglot.el
+++ b/lisp/progmodes/eglot.el
@@ -2371,23 +2371,31 @@ THINGS are either registrations or unregisterations (sic)."
2371 (_server (_method (eql window/showDocument)) &key 2371 (_server (_method (eql window/showDocument)) &key
2372 uri external takeFocus selection) 2372 uri external takeFocus selection)
2373 "Handle request window/showDocument." 2373 "Handle request window/showDocument."
2374 (if (eq external t) (browse-url uri) 2374 (let ((success t)
2375 ;; Use run-with-timer to avoid nested client requests like the 2375 (filename))
2376 ;; synchronous imenu case caused by which-func-mode. 2376 (cond
2377 (run-with-timer 2377 ((eq external t) (browse-url uri))
2378 0 nil 2378 ((file-readable-p (setq filename (eglot--uri-to-path uri)))
2379 (lambda () 2379 ;; Use run-with-timer to avoid nested client requests like the
2380 (with-current-buffer (find-file-noselect (eglot--uri-to-path uri)) 2380 ;; "synchronous imenu" floated in bug#62116 presumably caused by
2381 (cond (takeFocus 2381 ;; which-func-mode.
2382 (pop-to-buffer (current-buffer)) 2382 (run-with-timer
2383 (select-frame-set-input-focus (selected-frame))) 2383 0 nil
2384 ((display-buffer (current-buffer)))) 2384 (lambda ()
2385 (when selection 2385 (with-current-buffer (find-file-noselect filename)
2386 (eglot--widening 2386 (cond (takeFocus
2387 (pcase-let ((`(,beg . ,end) (eglot--range-region selection))) 2387 (pop-to-buffer (current-buffer))
2388 (goto-char beg) 2388 (select-frame-set-input-focus (selected-frame)))
2389 (pulse-momentary-highlight-region beg end 'highlight)))))))) 2389 ((display-buffer (current-buffer))))
2390 '(:success t)) 2390 (when selection
2391 (pcase-let ((`(,beg . ,end) (eglot--range-region selection)))
2392 ;; FIXME: it is very naughty to use someone else's `--'
2393 ;; function, but `xref--goto-char' happens to have
2394 ;; exactly the semantics we want vis-a-vis widening.
2395 (xref--goto-char beg)
2396 (pulse-momentary-highlight-region beg end 'highlight)))))))
2397 (t (setq success :json-false)))
2398 `(:success ,success)))
2391 2399
2392(defun eglot--TextDocumentIdentifier () 2400(defun eglot--TextDocumentIdentifier ()
2393 "Compute TextDocumentIdentifier object for current buffer." 2401 "Compute TextDocumentIdentifier object for current buffer."
diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el
index 7ab5bdc276f..0d99e270a3f 100644
--- a/lisp/use-package/use-package-core.el
+++ b/lisp/use-package/use-package-core.el
@@ -76,6 +76,7 @@
76 :functions 76 :functions
77 :preface 77 :preface
78 :if :when :unless 78 :if :when :unless
79 :vc
79 :no-require 80 :no-require
80 :catch 81 :catch
81 :after 82 :after
@@ -1151,7 +1152,8 @@ meaning:
1151 #'use-package-normalize-paths)) 1152 #'use-package-normalize-paths))
1152 1153
1153(defun use-package-handler/:load-path (name _keyword arg rest state) 1154(defun use-package-handler/:load-path (name _keyword arg rest state)
1154 (let ((body (use-package-process-keywords name rest state))) 1155 (let ((body (use-package-process-keywords name rest
1156 (plist-put state :load-path arg))))
1155 (use-package-concat 1157 (use-package-concat
1156 (mapcar #'(lambda (path) 1158 (mapcar #'(lambda (path)
1157 `(eval-and-compile (add-to-list 'load-path ,path))) 1159 `(eval-and-compile (add-to-list 'load-path ,path)))
@@ -1577,6 +1579,109 @@ no keyword implies `:all'."
1577 (when use-package-compute-statistics 1579 (when use-package-compute-statistics
1578 `((use-package-statistics-gather :config ',name t)))))) 1580 `((use-package-statistics-gather :config ',name t))))))
1579 1581
1582;;;; :vc
1583
1584(defun use-package-vc-install (arg &optional local-path)
1585 "Install a package with `package-vc.el'.
1586ARG is a list of the form (NAME OPTIONS REVISION), as returned by
1587`use-package-normalize--vc-arg'. If LOCAL-PATH is non-nil, call
1588`package-vc-install-from-checkout'; otherwise, indicating a
1589remote host, call `package-vc-install' instead."
1590 (pcase-let* ((`(,name ,opts ,rev) arg)
1591 (spec (if opts (cons name opts) name)))
1592 (unless (package-installed-p name)
1593 (if local-path
1594 (package-vc-install-from-checkout local-path (symbol-name name))
1595 (package-vc-install spec rev)))))
1596
1597(defun use-package-handler/:vc (name _keyword arg rest state)
1598 "Generate code to install package NAME, or do so directly.
1599When the use-package declaration is part of a byte-compiled file,
1600install the package during compilation; otherwise, add it to the
1601macro expansion and wait until runtime. The remaining arguments
1602are as follows:
1603
1604_KEYWORD is ignored.
1605
1606ARG is the normalized input to the `:vc' keyword, as returned by
1607the `use-package-normalize/:vc' function.
1608
1609REST is a plist of other (following) keywords and their
1610arguments, each having already been normalised by the respective
1611function.
1612
1613STATE is a plist of any state that keywords processed before
1614`:vc' (see `use-package-keywords') may have accumulated.
1615
1616Also see the Info node `(use-package) Creating an extension'."
1617 (let ((body (use-package-process-keywords name rest state))
1618 (local-path (car (plist-get state :load-path))))
1619 ;; See `use-package-handler/:ensure' for an explanation.
1620 (if (bound-and-true-p byte-compile-current-file)
1621 (funcall #'use-package-vc-install arg local-path) ; compile time
1622 (push `(use-package-vc-install ',arg ,local-path) body)))) ; runtime
1623
1624(defun use-package-normalize--vc-arg (arg)
1625 "Normalize possible arguments to the `:vc' keyword.
1626ARG is a cons-cell of approximately the form that
1627`package-vc-selected-packages' accepts, plus an additional `:rev'
1628keyword. If `:rev' is not given, it defaults to `:last-release'.
1629
1630Returns a list (NAME SPEC REV), where (NAME . SPEC) is compliant
1631with `package-vc-selected-packages' and REV is a (possibly nil,
1632indicating the latest commit) revision."
1633 (cl-flet* ((ensure-string (s)
1634 (if (and s (stringp s)) s (symbol-name s)))
1635 (ensure-symbol (s)
1636 (if (and s (stringp s)) (intern s) s))
1637 (normalize (k v)
1638 (pcase k
1639 (:rev (cond ((or (eq v :last-release) (not v)) :last-release)
1640 ((eq v :newest) nil)
1641 (t (ensure-string v))))
1642 (:vc-backend (ensure-symbol v))
1643 (_ (ensure-string v)))))
1644 (pcase-let ((valid-kws '(:url :branch :lisp-dir :main-file :vc-backend :rev))
1645 (`(,name . ,opts) arg))
1646 (if (stringp opts) ; (NAME . VERSION-STRING) ?
1647 (list name opts)
1648 ;; Error handling
1649 (cl-loop for (k _) on opts by #'cddr
1650 if (not (member k valid-kws))
1651 do (use-package-error
1652 (format "Keyword :vc received unknown argument: %s. Supported keywords are: %s"
1653 k valid-kws)))
1654 ;; Actual normalization
1655 (list name
1656 (cl-loop for (k v) on opts by #'cddr
1657 if (not (eq k :rev))
1658 nconc (list k (normalize k v)))
1659 (normalize :rev (plist-get opts :rev)))))))
1660
1661(defun use-package-normalize/:vc (name _keyword args)
1662 "Normalize possible arguments to the `:vc' keyword.
1663NAME is the name of the `use-package' declaration, _KEYWORD is
1664ignored, and ARGS it a list of arguments given to the `:vc'
1665keyword, the cdr of which is ignored.
1666
1667See `use-package-normalize--vc-arg' for most of the actual
1668normalization work. Also see the Info
1669node `(use-package) Creating an extension'."
1670 (let ((arg (car args)))
1671 (pcase arg
1672 ((or 'nil 't) (list name)) ; guess name
1673 ((pred symbolp) (list arg)) ; use this name
1674 ((pred stringp) (list name arg)) ; version string + guess name
1675 ((pred plistp) ; plist + guess name
1676 (use-package-normalize--vc-arg (cons name arg)))
1677 (`(,(pred symbolp) . ,(or (pred plistp) ; plist/version string + name
1678 (pred stringp)))
1679 (use-package-normalize--vc-arg arg))
1680 (_ (use-package-error "Unrecognised argument to :vc.\
1681 The keyword wants an argument of nil, t, a name of a package,\
1682 or a cons-cell as accepted by `package-vc-selected-packages', where \
1683 the accepted plist is augmented by a `:rev' keyword.")))))
1684
1580;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1685;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1581;; 1686;;
1582;;; The main macro 1687;;; The main macro
@@ -1666,7 +1771,9 @@ Usage:
1666 (compare with `custom-set-variables'). 1771 (compare with `custom-set-variables').
1667:custom-face Call `custom-set-faces' with each face definition. 1772:custom-face Call `custom-set-faces' with each face definition.
1668:ensure Loads the package using package.el if necessary. 1773:ensure Loads the package using package.el if necessary.
1669:pin Pin the package to an archive." 1774:pin Pin the package to an archive.
1775:vc Install the package directly from a version control system
1776 (using `package-vc.el')."
1670 (declare (indent defun)) 1777 (declare (indent defun))
1671 (unless (memq :disabled args) 1778 (unless (memq :disabled args)
1672 (macroexp-progn 1779 (macroexp-progn
diff --git a/lisp/use-package/use-package-ensure.el b/lisp/use-package/use-package-ensure.el
index e0ea982594e..395a0bbda00 100644
--- a/lisp/use-package/use-package-ensure.el
+++ b/lisp/use-package/use-package-ensure.el
@@ -182,7 +182,8 @@ manually updated package."
182 182
183;;;###autoload 183;;;###autoload
184(defun use-package-handler/:ensure (name _keyword ensure rest state) 184(defun use-package-handler/:ensure (name _keyword ensure rest state)
185 (let* ((body (use-package-process-keywords name rest state))) 185 (let* ((body (use-package-process-keywords name rest state))
186 (ensure (and (not (plist-member rest :vc)) ensure)))
186 ;; We want to avoid installing packages when the `use-package' macro is 187 ;; We want to avoid installing packages when the `use-package' macro is
187 ;; being macro-expanded by elisp completion (see `lisp--local-variables'), 188 ;; being macro-expanded by elisp completion (see `lisp--local-variables'),
188 ;; but still install packages when byte-compiling, to avoid requiring 189 ;; but still install packages when byte-compiling, to avoid requiring
diff --git a/lisp/windmove.el b/lisp/windmove.el
index 06ce16c0d42..746a440bacb 100644
--- a/lisp/windmove.el
+++ b/lisp/windmove.el
@@ -724,6 +724,8 @@ from the opposite side of the frame."
724 nil windmove-wrap-around 'nomini))) 724 nil windmove-wrap-around 'nomini)))
725 (cond ((or (null other-window) (window-minibuffer-p other-window)) 725 (cond ((or (null other-window) (window-minibuffer-p other-window))
726 (user-error "No window %s from selected window" dir)) 726 (user-error "No window %s from selected window" dir))
727 ((window-minibuffer-p (selected-window))
728 (user-error "Can't swap window with the minibuffer"))
727 (t 729 (t
728 (window-swap-states nil other-window))))) 730 (window-swap-states nil other-window)))))
729 731
diff --git a/m4/gnulib-common.m4 b/m4/gnulib-common.m4
index edb8572da25..a2b53d33dca 100644
--- a/m4/gnulib-common.m4
+++ b/m4/gnulib-common.m4
@@ -1,4 +1,4 @@
1# gnulib-common.m4 serial 86 1# gnulib-common.m4 serial 87
2dnl Copyright (C) 2007-2023 Free Software Foundation, Inc. 2dnl Copyright (C) 2007-2023 Free Software Foundation, Inc.
3dnl This file is free software; the Free Software Foundation 3dnl This file is free software; the Free Software Foundation
4dnl gives unlimited permission to copy and/or distribute it, 4dnl gives unlimited permission to copy and/or distribute it,
@@ -1053,6 +1053,7 @@ AC_DEFUN([gl_CC_GNULIB_WARNINGS],
1053 dnl -Wno-float-conversion >= 4.9 >= 3.9 1053 dnl -Wno-float-conversion >= 4.9 >= 3.9
1054 dnl -Wno-float-equal >= 3 >= 3.9 1054 dnl -Wno-float-equal >= 3 >= 3.9
1055 dnl -Wimplicit-fallthrough >= 7 >= 3.9 1055 dnl -Wimplicit-fallthrough >= 7 >= 3.9
1056 dnl -Wno-missing-field-initializers >= 4.0, < 11
1056 dnl -Wno-pedantic >= 4.8 >= 3.9 1057 dnl -Wno-pedantic >= 4.8 >= 3.9
1057 dnl -Wno-sign-compare >= 3 >= 3.9 1058 dnl -Wno-sign-compare >= 3 >= 3.9
1058 dnl -Wno-sign-conversion >= 4.3 >= 3.9 1059 dnl -Wno-sign-conversion >= 4.3 >= 3.9
@@ -1078,6 +1079,9 @@ AC_DEFUN([gl_CC_GNULIB_WARNINGS],
1078 #if __GNUC__ >= 7 || (__clang_major__ + (__clang_minor__ >= 9) > 3) 1079 #if __GNUC__ >= 7 || (__clang_major__ + (__clang_minor__ >= 9) > 3)
1079 -Wimplicit-fallthrough 1080 -Wimplicit-fallthrough
1080 #endif 1081 #endif
1082 #if __GNUC__ >= 4 && __GNUC__ < 11 && !defined __clang__
1083 -Wno-missing-field-initializers
1084 #endif
1081 #if __GNUC__ + (__GNUC_MINOR__ >= 8) > 4 || (__clang_major__ + (__clang_minor__ >= 9) > 3) 1085 #if __GNUC__ + (__GNUC_MINOR__ >= 8) > 4 || (__clang_major__ + (__clang_minor__ >= 9) > 3)
1082 -Wno-pedantic 1086 -Wno-pedantic
1083 #endif 1087 #endif
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index 840decbf5d5..6c773908e26 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -73,6 +73,7 @@
73(defvar tramp-persistency-file-name) 73(defvar tramp-persistency-file-name)
74(defvar tramp-remote-path) 74(defvar tramp-remote-path)
75(defvar tramp-remote-process-environment) 75(defvar tramp-remote-process-environment)
76(defvar tramp-use-connection-share)
76 77
77;; Needed for Emacs 27. 78;; Needed for Emacs 27.
78(defvar lock-file-name-transforms) 79(defvar lock-file-name-transforms)
@@ -6933,6 +6934,13 @@ This does not support external Emacs calls."
6933 "Check, whether an out-of-band method is used." 6934 "Check, whether an out-of-band method is used."
6934 (tramp-method-out-of-band-p tramp-test-vec 1)) 6935 (tramp-method-out-of-band-p tramp-test-vec 1))
6935 6936
6937(defun tramp--test-putty-p ()
6938 "Check, whether the method method usaes PuTTY.
6939This does not support connection share for more than two connections."
6940 (member
6941 (file-remote-p ert-remote-temporary-file-directory 'method)
6942 '("plink" "plinkx" "pscp" "psftp")))
6943
6936(defun tramp--test-rclone-p () 6944(defun tramp--test-rclone-p ()
6937 "Check, whether the remote host is offered by rclone. 6945 "Check, whether the remote host is offered by rclone.
6938This requires restrictions of file name syntax." 6946This requires restrictions of file name syntax."
@@ -7486,6 +7494,10 @@ process sentinels. They shall not disturb each other."
7486 (string-to-number (getenv "REMOTE_PARALLEL_PROCESSES")))) 7494 (string-to-number (getenv "REMOTE_PARALLEL_PROCESSES"))))
7487 ((getenv "EMACS_HYDRA_CI") 5) 7495 ((getenv "EMACS_HYDRA_CI") 5)
7488 (t 10))) 7496 (t 10)))
7497 ;; PuTTY-based methods can only share up to 10 connections.
7498 (tramp-use-connection-share
7499 (if (and (tramp--test-putty-p) (>= number-proc 10))
7500 'suppress (bound-and-true-p tramp-use-connection-share)))
7489 ;; On hydra, timings are bad. 7501 ;; On hydra, timings are bad.
7490 (timer-repeat 7502 (timer-repeat
7491 (cond 7503 (cond
diff --git a/test/lisp/use-package/use-package-tests.el b/test/lisp/use-package/use-package-tests.el
index 6374a0d1037..c8c20fc51cb 100644
--- a/test/lisp/use-package/use-package-tests.el
+++ b/test/lisp/use-package/use-package-tests.el
@@ -1951,6 +1951,60 @@
1951 (should (eq (nth 1 binding) 'ignore)) 1951 (should (eq (nth 1 binding) 'ignore))
1952 (should (eq (nth 2 binding) nil)))) 1952 (should (eq (nth 2 binding) nil))))
1953 1953
1954(ert-deftest use-package-test/:vc-1 ()
1955 (match-expansion
1956 (use-package foo :vc (:url "bar"))
1957 '(progn (use-package-vc-install '(foo (:url "bar") :last-release) nil)
1958 (require 'foo nil nil))))
1959
1960(ert-deftest use-package-test/:vc-2 ()
1961 (match-expansion
1962 (use-package foo
1963 :vc (baz . (:url "baz" :vc-backend "Git"
1964 :main-file qux.el :rev "rev-string")))
1965 '(progn (use-package-vc-install '(baz
1966 (:url "baz" :vc-backend Git :main-file "qux.el")
1967 "rev-string")
1968 nil)
1969 (require 'foo nil nil))))
1970
1971(ert-deftest use-package-test/:vc-3 ()
1972 (match-expansion
1973 (use-package foo :vc (bar . "baz"))
1974 '(progn (use-package-vc-install '(bar "baz") nil)
1975 (require 'foo nil nil))))
1976
1977(ert-deftest use-package-test/:vc-4 ()
1978 (match-expansion
1979 (use-package foo :vc (bar . (:url "baz" :rev :newest)))
1980 '(progn (use-package-vc-install '(bar (:url "baz") nil) nil)
1981 (require 'foo nil nil))))
1982
1983(ert-deftest use-package-test/:vc-5 ()
1984 (let ((load-path? '(pred (apply-partially
1985 #'string=
1986 (expand-file-name "bar" user-emacs-directory)))))
1987 (match-expansion
1988 (use-package foo :vc other-name :load-path "bar")
1989 `(progn (eval-and-compile
1990 (add-to-list 'load-path ,load-path?))
1991 (use-package-vc-install '(other-name) ,load-path?)
1992 (require 'foo nil nil)))))
1993
1994(ert-deftest use-package-test-normalize/:vc ()
1995 (should (equal '(foo "version-string")
1996 (use-package-normalize/:vc 'foo :vc '("version-string"))))
1997 (should (equal '(bar "version-string")
1998 (use-package-normalize/:vc 'foo :vc '((bar . "version-string")))))
1999 (should (equal '(foo (:url "bar") "baz")
2000 (use-package-normalize/:vc 'foo :vc '((:url "bar" :rev "baz")))))
2001 (should (equal '(foo)
2002 (use-package-normalize/:vc 'foo :vc '(t))))
2003 (should (equal '(foo)
2004 (use-package-normalize/:vc 'foo :vc nil)))
2005 (should (equal '(bar)
2006 (use-package-normalize/:vc 'foo :vc '(bar)))))
2007
1954;; Local Variables: 2008;; Local Variables:
1955;; no-byte-compile: t 2009;; no-byte-compile: t
1956;; no-update-autoloads: t 2010;; no-update-autoloads: t