commit 265f4ef70233c4708cbbdeb1850541570c40fdd6 (HEAD, refs/remotes/origin/master)
Author: Po Lu
Date: Sun Apr 17 04:06:52 2022 +0000
Make sure the ftcr font driver is used on Haiku when Cairo is enabled
* src/haikufont.c (syms_of_haikufont): [USE_BE_CAIRO]: Make sure
`ftcr' superseeds `haiku'.
diff --git a/src/haikufont.c b/src/haikufont.c
index f2ead5d6c2..4e81e57703 100644
--- a/src/haikufont.c
+++ b/src/haikufont.c
@@ -1096,6 +1096,10 @@ syms_of_haikufont (void)
DEFSYM (Qko, "ko");
DEFSYM (Qjp, "jp");
+#ifdef USE_BE_CAIRO
+ Fput (Qhaiku, Qfont_driver_superseded_by, Qftcr);
+#endif
+
font_cache = list (Qnil);
staticpro (&font_cache);
}
commit f1ba92448d1e573640547c68d9bed89fe5c43da0
Author: Paul Eggert
Date: Sat Apr 16 18:48:51 2022 -0700
Document encode-time caveats
* doc/lispref/os.texi (Time of Day, Time Conversion):
Move the warnings about DST being -1 to closer to where DST is
discussed, and reword and improve the discussions and warnings.
Be more precise about years before 1969 (possible west of UTC) vs the
Epoch. Mention some problems due to leap seconds, leap years,
daylight saving transitions, and time zone changes. Modernize
discussion of OS timestamp range. Prefer secular ‘BCE’ to religious
‘BC’. Omit discussion of decoded-time-add and make-decoded-time, as
they are in a library and are not always available; instead, mention
the library. Warn about common mistakes when doing simple date
arithmetic.
* src/timefns.c (Fencode_time): In doc string, mention date
arithmetic and tighten up the wording a bit.
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index 66689f43a9..8366689640 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -1303,10 +1303,16 @@ zone.
@cindex Lisp timestamp
@cindex timestamp, Lisp
+@cindex Coordinated Universal Time
+@cindex Universal Time
+@cindex UTC
+@cindex leap seconds
Many functions like @code{current-time} and @code{file-attributes}
return @dfn{Lisp timestamp} values that count seconds, and that can
represent absolute time by counting seconds since the @dfn{epoch} of
-1970-01-01 00:00:00 UTC.
+1970-01-01 00:00:00 UTC (Coordinated Universal Time). Typically these
+counts ignore leap seconds; however, GNU and some other operating
+systems can be configured to count leap seconds.
Although traditionally Lisp timestamps were integer pairs, their
form has evolved and programs ordinarily should not depend on the
@@ -1367,8 +1373,8 @@ Time values can be converted to and from calendrical and other forms.
Some of these conversions rely on operating system functions that
limit the range of possible time values, and signal an error such as
@samp{"Specified time is not representable"} if the
-limits are exceeded. For instance, a system may not support years
-before 1970, or years before 1901, or years far in the future.
+limits are exceeded. For instance, a system might not support
+timestamps before the epoch, or years far in the future.
You can convert a time value into
a human-readable string using @code{format-time-string}, into a Lisp
timestamp using @code{time-convert}, and into other forms using
@@ -1434,11 +1440,11 @@ to default to Universal Time with @code{(setenv "TZ" "UTC0")}. If
which is a platform-dependent default time zone.
The set of supported @env{TZ} strings is system-dependent. GNU and
-many other systems support the tzdata database, e.g.,
+many other systems support TZDB timezones, e.g.,
@samp{"America/New_York"} specifies the time zone and daylight saving
time history for locations near New York City. GNU and most other
systems support POSIX-style @env{TZ} strings, e.g.,
-@samp{"EST+5EDT,M4.1.0/2,M10.5.0/2"} specifies the rules used in New
+@samp{"EST5EDT,M4.1.0,M10.5.0"} specifies the rules used in New
York from 1987 through 2006. All systems support the string
@samp{"UTC0"} meaning Universal Time.
@@ -1490,18 +1496,20 @@ The operating system limits the range of time and zone values.
These functions convert time values (@pxref{Time of Day}) to Lisp
timestamps, or into calendrical information and vice versa.
- Many 32-bit operating systems are limited to system times containing
-32 bits of information in their seconds component; these systems
-typically handle only the times from 1901-12-13 20:45:52 through
-2038-01-19 03:14:07 Universal Time. However, 64-bit and some 32-bit operating
-systems have larger seconds components, and can represent times far in
-the past or future.
-
- Calendrical conversion functions always use the Gregorian calendar, even
-for dates before the Gregorian calendar was introduced. Year numbers
-count the number of years since the year 1 BC, and do not skip zero
+ Many operating systems use 64-bit signed integers to count seconds,
+and can represent times far in the past or future. However, some are
+more limited. For example, old-fashioned operating systems that use
+32-bit signed integers typically handle only times from 1901-12-13
+20:45:52 through 2038-01-19 03:14:07 Universal Time.
+
+ Calendrical conversion functions use the Gregorian calendar even for
+dates before the Gregorian calendar was introduced, and for dates in
+the far distant past or future for which the Gregorian calendar
+is wildly inaccurate and disagrees with common practice in scientific fields
+like astronomy and paleontology, which use Julian-calendar year lengths.
+Year numbers count since the year 1 BCE, and do not skip zero
as traditional Gregorian years do; for example, the year number
-@minus{}37 represents the Gregorian year 38 BC@.
+@minus{}37 represents the Gregorian year 38 BCE@.
@defun time-convert time &optional form
This function converts a time value into a Lisp timestamp.
@@ -1620,53 +1628,6 @@ To access (or alter) the elements in the time value, the
@code{decoded-time-month}, @code{decoded-time-year},
@code{decoded-time-weekday}, @code{decoded-time-dst} and
@code{decoded-time-zone} accessors can be used.
-
-For instance, to increase the year in a decoded time, you could say:
-
-@lisp
-(setf (decoded-time-year decoded-time)
- (+ (decoded-time-year decoded-time) 4))
-@end lisp
-
-Also see the following function.
-
-@end defun
-
-@defun decoded-time-add time delta
-This function takes a decoded time structure and adds @var{delta}
-(also a decoded time structure) to it. Elements in @var{delta} that
-are @code{nil} are ignored.
-
-For instance, if you want ``same time next month'', you
-could say:
-
-@lisp
-(let ((time (decode-time nil nil t))
- (delta (make-decoded-time :month 2)))
- (encode-time (decoded-time-add time delta)))
-@end lisp
-
-If this date doesn't exist (if you're running this on January 31st,
-for instance), then the date will be shifted back until you get a
-valid date (which will be February 28th or 29th, depending).
-
-Fields are added in a most to least significant order, so if the
-adjustment described above happens, it happens before adding days,
-hours, minutes or seconds.
-
-The values in @var{delta} can be negative to subtract values instead.
-
-The return value is a decoded time structure.
-@end defun
-
-@defun make-decoded-time &key second minute hour day month year dst zone
-Return a decoded time structure with only the given keywords filled
-out, leaving the rest @code{nil}. For instance, to get a structure
-that represents ``two months'', you could say:
-
-@lisp
-(make-decoded-time :month 2)
-@end lisp
@end defun
@defun encode-time time &rest obsolescent-arguments
@@ -1676,9 +1637,21 @@ It can act as the inverse of @code{decode-time}.
Ordinarily the first argument is a list
@code{(@var{second} @var{minute} @var{hour} @var{day} @var{month}
@var{year} @var{ignored} @var{dst} @var{zone})} that specifies a
-decoded time in the style of @code{decode-time}, so that
-@code{(encode-time (decode-time ...))} works. For the meanings of
-these list members, see the table under @code{decode-time}.
+decoded time in the style of @code{decode-time}. For the meanings of
+these list elements, see the table under @code{decode-time}.
+In particular, @var{dst} says how to interpret timestamps during a
+daylight saving fallback when timestamps are repeated.
+If @var{dst} is @minus{}1, the DST value is guessed; if it
+is @code{t} or @code{nil} the timestamp with that DST value
+is returned, with an error signaled if no such timestamp exists.
+Unfortunately a @var{dst} value of @code{t} or @code{nil} does not
+disambiguate timestamps duplicated when a TZDB-based timezone moves
+further west of Greenwich, such as disambiguating the two
+standard-time timestamps 2020-12-27 01:30 when @var{zone} is
+@samp{"Europe/Volgograd"}, which at 02:00 that day changed
+standard time from 4 to 3 hours east of Greenwich; if you need to
+handle situations like this you can use a numeric @var{zone} to
+disambiguate instead.
As an obsolescent calling convention, this function can be given six
or more arguments. The first six arguments @var{second},
@@ -1687,14 +1660,18 @@ specify most of the components of a decoded time. If there are more
than six arguments the @emph{last} argument is used as @var{zone} and
any other extra arguments are ignored, so that @code{(apply
#'encode-time (decode-time ...))} works. In this obsolescent
-convention, @var{zone} defaults to the current time zone rule
-(@pxref{Time Zone Rules}), and @var{dst} is treated as if it was
-@minus{}1.
+convention, @var{dst} is @minus{}1 and @var{zone} defaults to the
+current time zone rule (@pxref{Time Zone Rules}).
+When modernizing an obsolescent caller, ensure that the more-modern
+list equivalent contains 9 elements with a a @code{dst} element that
+is @minus{}1, not @code{nil}.
Year numbers less than 100 are not treated specially. If you want them
to stand for years above 1900, or years above 2000, you must alter them
yourself before you call @code{encode-time}.
The operating system limits the range of time and zone values.
+However, timestamps ranging from the epoch to the near future are
+always supported.
The @code{encode-time} function acts as a rough inverse to
@code{decode-time}. For example, you can pass the output of
@@ -1707,25 +1684,27 @@ the latter to the former as follows:
You can perform simple date arithmetic by using out-of-range values for
@var{seconds}, @var{minutes}, @var{hour}, @var{day}, and @var{month};
for example, day 0 means the day preceding the given month.
+Take care when doing so, as it is common for this to fail in some cases.
+For example:
+
+@lisp
+;; Try to compute the time four years from now.
+;; Watch out; this might not work as expected.
+(let ((time (decode-time)))
+ (setf (decoded-time-year time)
+ (+ (decoded-time-year time) 4))
+ time)
+@end lisp
-The old and the new styles to call @code{encode-time} with the same
-values of time fields may give different results. While modernizing
-code that uses obsolescent calling convention, ensure that the list
-argument contains 9 elements. Pay special attention that the @code{dst}
-field does not use @code{nil} expecting that actual value will be
-guessed, pass @samp{-1} instead. During normalizing of values to
-correct state of daylight saving time users may get time shift and even
-wrong date. It may take months to discover such problem. When
-called with multiple arguments, the function ignores equivalent of the
-@code{dst} value and @samp{-1} is effectively used. The new way to call
-@code{encode-time} has an advantage that it is possible to resolve
-ambiguity around backward time shift by passing @code{nil} or @code{t}.
-Unfortunately there are enough cases across the world when a particular
-area is moved to another time zone with no change of daylight saving
-time state. @code{encode-time} may signal an error in response to
-@code{t} passed as @code{dst}. You have to pass @code{zone} explicitly
-as time offset in such case if default ambiguity resolution is not
-acceptable.
+@noindent
+Unfortunately, this code might not work as expected if the resulting
+time is invalid due to daylight saving transitions, time zone changes,
+or missing leap days or leap seconds. For example, if executed on
+February 29, 2096 this code yields a nonexistent date because 2100 is
+not a leap year. To avoid some (though not all) of the problem, you
+can base calculations on the middle of the affected unit, e.g., start
+at July 1 when adding years. Alternatively, you can use the
+@file{calendar} and @file{time-date} libraries.
@end defun
@node Time Parsing
diff --git a/src/timefns.c b/src/timefns.c
index 9af89a512d..7a4a7075ed 100644
--- a/src/timefns.c
+++ b/src/timefns.c
@@ -1609,11 +1609,11 @@ check_tm_member (Lisp_Object obj, int offset)
DEFUN ("encode-time", Fencode_time, Sencode_time, 1, MANY, 0,
doc: /* Convert TIME to a timestamp.
-TIME is a list (SECOND MINUTE HOUR DAY MONTH YEAR IGNORED DST ZONE).
+TIME is a list (SECOND MINUTE HOUR DAY MONTH YEAR IGNORED DST ZONE)
in the style of `decode-time', so that (encode-time (decode-time ...)) works.
In this list, ZONE can be nil for Emacs local time, t for Universal
Time, `wall' for system wall clock time, or a string as in the TZ
-environment variable. It can also be a list (as from
+environment variable. ZONE can also be a list (as from
`current-time-zone') or an integer (as from `decode-time') applied
without consideration for daylight saving time. If ZONE specifies a
time zone with daylight-saving transitions, DST is t for daylight
@@ -1626,14 +1626,12 @@ DAY, MONTH, and YEAR, and specify the components of a decoded time.
If there are more than 6 arguments the *last* argument is used as ZONE
and any other extra arguments are ignored, so that (apply
#\\='encode-time (decode-time ...)) works. In this obsolescent
-convention, DST and ZONE default to -1 and nil respectively.
+convention, DST is -1 and ZONE defaults to nil.
-Years before 1970 are not guaranteed to work. On some systems,
-year values as low as 1901 do work.
-
-See Info node `(elisp)Time Conversion' for description of a pitfall
-that can be faced during migration from the obsolescent to the new
-calling convention due to unconscious usage of nil for the DST argument.
+The range of supported years is at least 1970 to the near future.
+Out-of-range values for SECOND through MONTH are brought into range
+via date arithmetic. This can be tricky especially when combined with
+DST; see Info node `(elisp)Time Conversion' for details and caveats.
usage: (encode-time TIME &rest OBSOLESCENT-ARGUMENTS) */)
(ptrdiff_t nargs, Lisp_Object *args)
commit 15a5cf9a9aa7798ee12ae96b8b6b4efe1562b57e
Author: Max Nikulin
Date: Sat Apr 16 18:48:51 2022 -0700
Stress difference of new and old ways to call `encode-time'
* doc/lispref/os.texi (Time Conversion): Add a warning that blind
changing of code calling `encode-time' to use single list instead of
multiple values may cause deferred bugs since it is common to use nil
for ignored arguments such as DST in the old calling convention.
* src/timefns.c (encode-time): Mention the warning added to the elisp
reference in the docstring.
Refactoring related to `encode-time' caused (bug#54731), so it is better
to make apparent the difference between the recommended and the
obsolescent ways to call the function. More details concerning the
purpose and limitations of the DST field are added after discussion with
Paul Eggert in (bug#54764).
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index 30883402f9..66689f43a9 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -1707,6 +1707,25 @@ the latter to the former as follows:
You can perform simple date arithmetic by using out-of-range values for
@var{seconds}, @var{minutes}, @var{hour}, @var{day}, and @var{month};
for example, day 0 means the day preceding the given month.
+
+The old and the new styles to call @code{encode-time} with the same
+values of time fields may give different results. While modernizing
+code that uses obsolescent calling convention, ensure that the list
+argument contains 9 elements. Pay special attention that the @code{dst}
+field does not use @code{nil} expecting that actual value will be
+guessed, pass @samp{-1} instead. During normalizing of values to
+correct state of daylight saving time users may get time shift and even
+wrong date. It may take months to discover such problem. When
+called with multiple arguments, the function ignores equivalent of the
+@code{dst} value and @samp{-1} is effectively used. The new way to call
+@code{encode-time} has an advantage that it is possible to resolve
+ambiguity around backward time shift by passing @code{nil} or @code{t}.
+Unfortunately there are enough cases across the world when a particular
+area is moved to another time zone with no change of daylight saving
+time state. @code{encode-time} may signal an error in response to
+@code{t} passed as @code{dst}. You have to pass @code{zone} explicitly
+as time offset in such case if default ambiguity resolution is not
+acceptable.
@end defun
@node Time Parsing
diff --git a/src/timefns.c b/src/timefns.c
index b061be0a78..9af89a512d 100644
--- a/src/timefns.c
+++ b/src/timefns.c
@@ -1631,6 +1631,10 @@ convention, DST and ZONE default to -1 and nil respectively.
Years before 1970 are not guaranteed to work. On some systems,
year values as low as 1901 do work.
+See Info node `(elisp)Time Conversion' for description of a pitfall
+that can be faced during migration from the obsolescent to the new
+calling convention due to unconscious usage of nil for the DST argument.
+
usage: (encode-time TIME &rest OBSOLESCENT-ARGUMENTS) */)
(ptrdiff_t nargs, Lisp_Object *args)
{
commit 18ec3fcce952efee283bfd6599a9de5f78f14a26
Author: Po Lu
Date: Sun Apr 17 08:38:37 2022 +0800
Restore pending_signals at a point in the DND event loop
* src/xterm.c (x_dnd_begin_drag_and_drop): Restore
pending_signals after unblock_input.
diff --git a/src/xterm.c b/src/xterm.c
index b65de88674..89dd28c0d5 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -9465,6 +9465,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
XTextProperty prop;
xm_drop_start_message dmsg;
Lisp_Object frame_object, x, y, frame, local_value;
+ bool signals_were_pending;
#ifdef HAVE_XKB
XkbStateRec keyboard_state;
#endif
@@ -9674,7 +9675,12 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
&next_event, &finish, &hold_quit);
#endif
#endif
+ /* The unblock_input below might try to read input, but
+ XTread_socket does nothing inside a drag-and-drop event
+ loop, so don't let it clear the pending_signals flag. */
+ signals_were_pending = pending_signals;
unblock_input ();
+ pending_signals = signals_were_pending;
if (x_dnd_movement_frame)
{
commit 3145449ddbfe333f69c8588d249f6733fdeb2f28
Author: Earl Hyatt
Date: Mon Dec 6 21:04:27 2021 -0500
Add basic Texinfo support for Flymake.
* lisp/textmodes/texinfo.el (texinfo-flymake, texinfo--flymake-proc)
(texinfo-mode):
Add the functions texinfo-flymake and process variable
texinfo--flymake-proc. Modify texinfo-mode to automatically add this
function to the hook flymake-diagnostic-functions.
diff --git a/lisp/textmodes/texinfo.el b/lisp/textmodes/texinfo.el
index 7f6ed3d1da..71b8d82ed9 100644
--- a/lisp/textmodes/texinfo.el
+++ b/lisp/textmodes/texinfo.el
@@ -31,6 +31,16 @@
;;; Code:
+(eval-when-compile (require 'cl-lib)
+ (require 'flymake)
+ (require 'rx))
+(declare-function flymake-diag-region "flymake"
+ (buffer line &optional col))
+(declare-function flymake-make-diagnostic "flymake"
+ ( locus beg end type text
+ &optional data overlay-properties))
+(declare-function flymake--log-1 (level sublog msg &rest args))
+
(eval-when-compile (require 'tex-mode))
(declare-function tex-buffer "tex-mode" ())
(declare-function tex-region "tex-mode" (beg end))
@@ -335,6 +345,69 @@ Subexpression 1 is what goes into the corresponding `@end' statement.")
(if (re-search-backward "^@node[ \t]+\\([^,\n]+\\)" nil t)
(match-string-no-properties 1))))
+;;; Flymake support
+(defvar-local texinfo--flymake-proc nil)
+(defun texinfo-flymake (report-fn &rest _)
+ "Texinfo checking for Flymake.
+
+REPORT-FN is the callback function."
+ (let ((executable (or (executable-find "makeinfo")
+ (executable-find "texi2any")))
+ (source (current-buffer)))
+
+ (unless executable
+ (error "Flymake for Texinfo requires `makeinfo' or `texi2any'"))
+
+ (when (process-live-p texinfo--flymake-proc)
+ (kill-process texinfo--flymake-proc))
+
+ (save-restriction
+ (widen)
+ (setq texinfo--flymake-proc
+ (make-process
+ :name "texinfo-flymake"
+ :noquery t
+ :connection-type 'pipe
+ :buffer (generate-new-buffer " *texinfo-flymake*")
+ :command `(,executable "-o" ,null-device "-")
+ :sentinel
+ (lambda (proc _event)
+ (when (memq (process-status proc) '(exit signal))
+ (unwind-protect
+ (if (eq (buffer-local-value 'texinfo--flymake-proc
+ source)
+ proc)
+ (with-current-buffer (process-buffer proc)
+ (goto-char (point-min))
+ (cl-loop
+ while (search-forward-regexp
+ (rx line-start
+ "-:"
+ (group-n 1 (0+ digit)) ; Line
+ (optional ":" (group-n 2 (0+ digit))) ; col
+ ": "
+ (optional (group-n 3 "warning: ")) ; warn
+ (group-n 4 (0+ nonl)) ; Message
+ line-end)
+ nil t)
+ for msg = (match-string 4)
+ for (beg . end) = (flymake-diag-region
+ source
+ (string-to-number (match-string 1)))
+ for type = (if (match-string 3)
+ :warning
+ :error)
+ collect (flymake-make-diagnostic
+ source beg end type msg)
+ into diags
+ finally (funcall report-fn diags)))
+ (flymake-log :warning "Cancelling obsolete check %s"
+ proc))
+ (kill-buffer (process-buffer proc)))))))
+ (process-send-region texinfo--flymake-proc (point-min) (point-max))
+ (process-send-eof texinfo--flymake-proc))))
+
+
;;; Texinfo mode
;;;###autoload
@@ -454,7 +527,10 @@ value of `texinfo-mode-hook'."
(let ((prevent-filling "^@\\(def\\|multitable\\)"))
(if (null auto-fill-inhibit-regexp)
prevent-filling
- (concat auto-fill-inhibit-regexp "\\|" prevent-filling)))))
+ (concat auto-fill-inhibit-regexp "\\|" prevent-filling))))
+
+ ;; Set up Flymake support.
+ (add-hook 'flymake-diagnostic-functions #'texinfo-flymake nil t))
(defvar texinfo-fillable-commands '("@noindent")
"A list of commands that can be filled.")
commit 79f2494680998f80264d389903ccbca08a179ad5
Merge: bf7fc3efbf 6831008a27
Author: Eli Zaretskii
Date: Sat Apr 16 14:05:54 2022 -0400
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
Merge from emacs-28.
commit bf7fc3efbf07dd2eff96107c5dd0c7d28a22ccff
Merge: 44ba0270b7 1c495aff71
Author: Eli Zaretskii
Date: Sat Apr 16 13:58:34 2022 -0400
; Merge from origin/emacs-28
The following commit was skipped:
1c495aff71 Clarify when mode tagging is used
commit 44ba0270b7ea8d193ceb7d9ad10937b03f6b5244
Merge: 1cc32c6c19 d53c999b4a
Author: Eli Zaretskii
Date: Sat Apr 16 13:58:31 2022 -0400
Merge from origin/emacs-28
d53c999b4a Further vcs-cvs/rcs-responsible-p updates from master
dc3d1628ec ; * src/sysdep.c: Fix mistake in previous commit
855e15dbf1 Fix builds on older versions of macOS
9da744e450 Fix documentation of Outline minor mode options
a8bb12ab05 Improve discoverability of 'insert-directory-program'
3f166bdf44 ; * etc/PROBLEMS: Describe MS-Windows issues with fonts. ...
803ac857ee Fix cursor motion under truncate-lines with Flymake fringe...
# Conflicts:
# etc/PROBLEMS
# lisp/outline.el
# src/sysdep.c
commit 1cc32c6c193c935b7640a16e195bbf04156726c2
Merge: 6ecb7ff5ec bc63651588
Author: Eli Zaretskii
Date: Sat Apr 16 13:46:05 2022 -0400
; Merge from origin/emacs-28
The following commit was skipped:
bc63651588 Make all vc-*-responsible-p functions return a string
commit 6ecb7ff5ec9492a8671df63ae097ca2045d18494
Merge: 25db9dfae0 b201823f63
Author: Eli Zaretskii
Date: Sat Apr 16 13:46:04 2022 -0400
Merge from origin/emacs-28
b201823f63 Describe problems with invoking Python on MS-Windows
880f2734c9 A better fix for bug#54800
5ee959aa87 Add a comment about cl-concatenate
ab2b822b9b Revert "Make cl-concatenate an alias of seq-concatenate"
commit 25db9dfae00b2638f167d078a076108b8c911fbf
Merge: 8804dfdb1a 78e1640ad5
Author: Eli Zaretskii
Date: Sat Apr 16 13:46:04 2022 -0400
; Merge from origin/emacs-28
The following commit was skipped:
78e1640ad5 Fix 'window-text-pixel-width' when starting from display p...
commit 8804dfdb1a7337aae8eaa48924692fd65d0916e2
Merge: cb953504ab 5e47d6284b
Author: Eli Zaretskii
Date: Sat Apr 16 13:45:50 2022 -0400
Merge from origin/emacs-28
5e47d6284b * lisp/gnus/mm-encode.el (mm-default-file-encoding): Fix "...
e71c7a7c60 Fix default-directory of buffers visiting files in renamed...
cccaa9c31d Fix a kill-append regression
33828e4818 * doc/misc/eww.texi (Advanced): Correct outdated info (bug...
e8d2f40f41 Clean up the MSDOS port
338eda09d8 Fix typo in next-error-find-buffer-function
# Conflicts:
# doc/misc/eww.texi
commit cb953504abf45a85a6c5bcdd118315d5217e6226
Merge: 5890b80bca b385fd0b88
Author: Eli Zaretskii
Date: Sat Apr 16 13:43:33 2022 -0400
; Merge from origin/emacs-28
The following commit was skipped:
b385fd0b88 Revert "Make shell-resync-dirs handle whitespace in direct...
commit 5890b80bca13b48c6c3fd26ac2721db7f3a3d013
Merge: 6339fcffa1 84a2857722
Author: Eli Zaretskii
Date: Sat Apr 16 13:43:33 2022 -0400
Merge from origin/emacs-28
84a2857722 Fix scrolling of the stack window in Calc
9dd44505b1 ; * src/window.c (Fset_window_start): Clarify the effect o...
24a6c7c8c0 Update and fix instructions and scripts for updating the W...
886339747b Extend tramp-archive-test45-auto-load
ff997ad786 Ensure local `default-directory' in Tramp when needed
4f27588a16 Clarify "idleness" in the ELisp manual
commit 6339fcffa1d409fc8c7a82867a89547c453d8bc1
Merge: e495a3d79b 98abf01fd6
Author: Eli Zaretskii
Date: Sat Apr 16 13:43:33 2022 -0400
; Merge from origin/emacs-28
The following commit was skipped:
98abf01fd6 Use correct signal oldset in posix_spawn implementation
commit e495a3d79b2ac0310122757694ce27b25b72d6bd
Merge: e888cee1f9 aab36e1895
Author: Eli Zaretskii
Date: Sat Apr 16 13:43:32 2022 -0400
Merge from origin/emacs-28
aab36e1895 Fix error in tramp-archive-autoload-file-name-handler
11a1f7817e Merge branch 'emacs-28' of git.sv.gnu.org:/srv/git/emacs i...
93974198b6 Commit missing file from previous commit
commit e888cee1f911a8321bd784b7d3c7f573b3a67bd5
Merge: e8fd3a2a2d 71f51f1b9d
Author: Eli Zaretskii
Date: Sat Apr 16 13:43:32 2022 -0400
; Merge from origin/emacs-28
The following commits were skipped:
71f51f1b9d Commit missing file from previous commit (Do not merge wit...
009e88e002 Merge with Tramp 2.5.2.3 (Do not merge with master)
4161a36849 cl-generic.el: Fix bug#46722
commit e8fd3a2a2da1d339cc541aace95823376ccd52a2
Merge: d64ad72bcc 8c71ac606e
Author: Eli Zaretskii
Date: Sat Apr 16 13:43:32 2022 -0400
Merge from origin/emacs-28
8c71ac606e Fix fallout from lexical-binding in vhdl-mode.el
commit d64ad72bccc715a1ca77273abd9e31799bf978ec
Merge: 4916c827ec dd3863d8bc
Author: Eli Zaretskii
Date: Sat Apr 16 13:43:31 2022 -0400
; Merge from origin/emacs-28
The following commit was skipped:
dd3863d8bc ; Prepare the release branch for Emacs-28.2 development
commit 6831008a2721b06457f4613ebcd974721781c22c
Author: Lars Ingebrigtsen
Date: Sat Apr 16 19:42:44 2022 +0200
Regenerated ldefs-boot.el
diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el
index e03535483a..77f6b980ac 100644
--- a/lisp/ldefs-boot.el
+++ b/lisp/ldefs-boot.el
@@ -10416,7 +10416,12 @@ some major modes from being locked under some circumstances.
;;; Generated autoloads from textmodes/emacs-news-mode.el
(autoload 'emacs-news-mode "emacs-news-mode" "\
-Major mode for editing and viewind the Emacs NEWS file.
+Major mode for editing the Emacs NEWS file.
+
+\(fn)" t nil)
+
+(autoload 'emacs-news-view-mode "emacs-news-mode" "\
+Major mode for viewing the Emacs NEWS file.
\(fn)" t nil)
@@ -27016,6 +27021,8 @@ is non-nil, the command will not ask the user for confirmation.
NO-CONFIRM is always nil when the command is invoked
interactively.
+Also see the `project-kill-buffers-display-buffer-list' variable.
+
\(fn &optional NO-CONFIRM)" t nil)
(autoload 'project-remember-project "project" "\
commit 1a339d6ba5372e93ce62d7cfa0dcc2072610cdd7
Author: Lars Ingebrigtsen
Date: Sat Apr 16 19:42:33 2022 +0200
Don't leave `C-h N' in a text-mode derived mode
* lisp/help.el (view-emacs-news): Use emacs-news-view-mode.
* lisp/textmodes/emacs-news-mode.el (emacs-news-view-mode): Split
into own mode to avoid confusion.
diff --git a/lisp/help.el b/lisp/help.el
index e326ea5d00..9cde65f797 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -453,10 +453,9 @@ With argument, display info only for the selected version."
((< vn 18) "NEWS.1-17")
(t (format "NEWS.%d" vn))))
res)
- (find-file (expand-file-name file data-directory))
- (setq buffer-read-only t)
- (emacs-news-mode)
- (widen)
+ (let ((inhibit-local-variables-regexps '(".*")))
+ (find-file (expand-file-name file data-directory))
+ (emacs-news-view-mode))
(goto-char (point-min))
(when (stringp version)
(when (re-search-forward
diff --git a/lisp/textmodes/emacs-news-mode.el b/lisp/textmodes/emacs-news-mode.el
index a766352917..e31a7105b8 100644
--- a/lisp/textmodes/emacs-news-mode.el
+++ b/lisp/textmodes/emacs-news-mode.el
@@ -50,18 +50,26 @@
`(("^---$" 0 'emacs-news-does-not-need-documentation)
("^\\+\\+\\+$" 0 'emacs-news-is-documented)))
-;;;###autoload
-(define-derived-mode emacs-news-mode text-mode "NEWS"
- "Major mode for editing and viewind the Emacs NEWS file."
+(defun emacs-news--mode-common ()
(setq-local font-lock-defaults '(emacs-news-mode-font-lock-keywords t))
(setq-local outline-regexp "^\\*+ "
outline-minor-mode-cycle t
outline-minor-mode-highlight 'append)
+ (outline-minor-mode))
+
+;;;###autoload
+(define-derived-mode emacs-news-mode text-mode "NEWS"
+ "Major mode for editing the Emacs NEWS file."
(setq-local fill-paragraph-function #'emacs-news--fill-paragraph)
- (outline-minor-mode 1)
- (when buffer-read-only
- (emacs-news--buttonize)
- (button-mode)))
+ (emacs-news--mode-common))
+
+;;;###autoload
+(define-derived-mode emacs-news-view-mode special-mode "NEWS"
+ "Major mode for viewing the Emacs NEWS file."
+ (setq buffer-read-only t)
+ (emacs-news--buttonize)
+ (button-mode)
+ (emacs-news--mode-common))
(defun emacs-news--fill-paragraph (&optional justify)
(cond
commit 10c48b7080d0ee63a7515a87ff17a1dfb4f38fb2
Author: Lars Ingebrigtsen
Date: Sat Apr 16 19:32:26 2022 +0200
Fix button-buffer-map binding error
* lisp/button.el (button-buffer-map): Fix error in map rewriting
in previous commit.
diff --git a/lisp/button.el b/lisp/button.el
index 244201be2d..80b73033d6 100644
--- a/lisp/button.el
+++ b/lisp/button.el
@@ -56,10 +56,10 @@
:group 'basic-faces)
(defvar-keymap button-buffer-map
- :doc "Keymap useful for buffers containing buttons.
+ :doc "Keymap useful for buffers containing buttons.
Mode-specific keymaps may want to use this as their parent keymap."
"TAB" #'forward-button
- "C-TAB" #'backward-button
+ "ESC TAB" #'backward-button
"" #'backward-button)
(defvar-keymap button-map
commit 4916c827ec62a8f22ca054b1df4cfc8227601793
Author: Lars Ingebrigtsen
Date: Sat Apr 16 19:14:34 2022 +0200
Add new commands to go to headings/sections in the NEWS file
* lisp/textmodes/emacs-news-mode.el (emacs-news-find-heading)
(emacs-news-goto-section): New commands.
diff --git a/lisp/textmodes/emacs-news-mode.el b/lisp/textmodes/emacs-news-mode.el
index 85cbb1847b..a766352917 100644
--- a/lisp/textmodes/emacs-news-mode.el
+++ b/lisp/textmodes/emacs-news-mode.el
@@ -42,6 +42,8 @@
(defvar-keymap emacs-news-mode-map
"C-c C-s" #'emacs-news-next-untagged-entry
"C-c C-r" #'emacs-news-previous-untagged-entry
+ "C-c C-g" #'emacs-news-goto-section
+ "C-c C-f" #'emacs-news-find-heading
"C-c C-n" #'emacs-news-count-untagged-entries)
(defvar emacs-news-mode-font-lock-keywords
@@ -99,19 +101,15 @@ untagged NEWS entry."
(funcall (if reverse #'re-search-backward
#'re-search-forward)
"^\\(\\*+\\) " nil t))
- (unless (save-excursion
- (forward-line -1)
- (looking-at "---$\\|\\+\\+\\+$"))
- ;; We have an entry without a tag before it, but check whether
- ;; it's a heading (which we can determine if the next entry has
- ;; more asterisks).
- (let ((level (length (match-string 1))))
- (when (save-excursion
- (goto-char (match-end 0))
- (re-search-forward "^\\(\\*+\\) " nil t))
- (when (<= (length (match-string 1)) level)
- ;; It wasn't a sub-heading, so we've found one.
- (setq found t))))))
+ (when (and (not (save-excursion
+ (forward-line -1)
+ (looking-at "---$\\|\\+\\+\\+$")))
+ ;; We have an entry without a tag before it, but
+ ;; check whether it's a heading (which we can
+ ;; determine if the next entry has more asterisks).
+ (not (emacs-news--heading-p)))
+ ;; It wasn't a sub-heading, so we've found one.
+ (setq found t)))
(if found
(progn
(push-mark start)
@@ -122,6 +120,15 @@ untagged NEWS entry."
(goto-char start)
nil)))
+(defun emacs-news--heading-p ()
+ (save-excursion
+ (beginning-of-line)
+ (and (looking-at "\\(\\*+\\) ")
+ (let ((level (length (match-string 1))))
+ (goto-char (match-end 0))
+ (when (re-search-forward "^\\(\\*+\\) " nil t)
+ (> (length (match-string 1)) level))))))
+
(defun emacs-news-previous-untagged-entry ()
"Go to the previous untagged NEWS entry."
(interactive nil emacs-news-mode)
@@ -166,6 +173,38 @@ untagged NEWS entry."
(lambda (node) (info node))
(match-string 1)))))))
+(defun emacs-news--sections (regexp)
+ (let ((sections nil))
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward (concat "^" regexp "\\(.*\\)") nil t)
+ (when (save-match-data (emacs-news--heading-p))
+ (push (buffer-substring-no-properties
+ (match-beginning 1) (match-end 1))
+ sections))))
+ (nreverse sections)))
+
+(defun emacs-news-goto-section (section)
+ "Go to SECTION in the Emacs NEWS file."
+ (interactive (list
+ (completing-read "Goto section: " (emacs-news--sections "\\* ")
+ nil t))
+ emacs-news-mode)
+ (goto-char (point-min))
+ (when (search-forward (concat "\n* " section) nil t)
+ (beginning-of-line)))
+
+(defun emacs-news-find-heading (heading)
+ "Go to HEADING in the Emacs NEWS file."
+ (interactive (list
+ (completing-read "Goto heading: "
+ (emacs-news--sections "\\*\\*\\*? ")
+ nil t))
+ emacs-news-mode)
+ (goto-char (point-min))
+ (when (re-search-forward (concat "^*+ " (regexp-quote heading)) nil t)
+ (beginning-of-line)))
+
(provide 'emacs-news-mode)
;;; emacs-news-mode.el ends here
commit 0b9631836a28752ea682896cd18d51f16ca51b93
Author: Eli Zaretskii
Date: Sat Apr 16 19:37:00 2022 +0300
; * doc/emacs/mini.texi (Completion Commands): Fix markup.
diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi
index 6012d2f280..20282d5378 100644
--- a/doc/emacs/mini.texi
+++ b/doc/emacs/mini.texi
@@ -379,8 +379,8 @@ used with the completion list:
@table @kbd
@vindex minibuffer-completion-auto-choose
-@item M-
-@itemx @key{M-}
+@item M-@key{DOWN}
+@itemx M-@key{UP}
@findex previous-completion
@findex next-completion
These keys will navigate through the completions displayed in the
@@ -389,8 +389,8 @@ non-@code{nil} (which is the default), using these commands will
automatically insert the current completion candidate in the
minibuffer. If this user option is @code{nil}, the keys will navigate
the same way as before, but won't automatically insert the candidate
-in the minibuffer. Instead you have to use the @key{M-RET} command to
-do that. With a prefix argument, @key{C-u M-RET} inserts the
+in the minibuffer. Instead you have to use the @kbd{M-@key{RET}} command to
+do that. With a prefix argument, @kbd{C-u M-@key{RET}} inserts the
currently active candidate to the minibuffer, but doesn't exit the
minibuffer.
commit 9b0940420e811ab7d819db9e6ad841591a60b873
Author: Lars Ingebrigtsen
Date: Sat Apr 16 18:35:11 2022 +0200
Add emacs-news-previous-untagged-entry command
* lisp/textmodes/emacs-news-mode.el
(emacs-news-next-untagged-entry): Allow searching backward.
(emacs-news-previous-untagged-entry): New command and keystroke.
diff --git a/lisp/textmodes/emacs-news-mode.el b/lisp/textmodes/emacs-news-mode.el
index 340187e5fd..85cbb1847b 100644
--- a/lisp/textmodes/emacs-news-mode.el
+++ b/lisp/textmodes/emacs-news-mode.el
@@ -41,6 +41,7 @@
(defvar-keymap emacs-news-mode-map
"C-c C-s" #'emacs-news-next-untagged-entry
+ "C-c C-r" #'emacs-news-previous-untagged-entry
"C-c C-n" #'emacs-news-count-untagged-entries)
(defvar emacs-news-mode-font-lock-keywords
@@ -83,16 +84,21 @@
(t
(fill-paragraph justify))))
-(defun emacs-news-next-untagged-entry ()
- "Go to the next untagged NEWS entry."
- (interactive nil emacs-news-mode)
+(defun emacs-news-next-untagged-entry (&optional reverse)
+ "Go to the next untagged NEWS entry.
+If REVERSE (interactively, the prefix), go to the previous
+untagged NEWS entry."
+ (interactive "P" emacs-news-mode)
(let ((start (point))
(found nil))
;; Don't consider the current line, because that would stop
;; progress if calling this command repeatedly.
- (forward-line 1)
+ (unless reverse
+ (forward-line 1))
(while (and (not found)
- (re-search-forward "\\(\\*+\\) " nil t))
+ (funcall (if reverse #'re-search-backward
+ #'re-search-forward)
+ "^\\(\\*+\\) " nil t))
(unless (save-excursion
(forward-line -1)
(looking-at "---$\\|\\+\\+\\+$"))
@@ -101,6 +107,7 @@
;; more asterisks).
(let ((level (length (match-string 1))))
(when (save-excursion
+ (goto-char (match-end 0))
(re-search-forward "^\\(\\*+\\) " nil t))
(when (<= (length (match-string 1)) level)
;; It wasn't a sub-heading, so we've found one.
@@ -115,6 +122,11 @@
(goto-char start)
nil)))
+(defun emacs-news-previous-untagged-entry ()
+ "Go to the previous untagged NEWS entry."
+ (interactive nil emacs-news-mode)
+ (emacs-news-next-untagged-entry t))
+
(defun emacs-news-count-untagged-entries ()
"Say how many untagged entries there are in the current NEWS buffer."
(interactive nil emacs-news-mode)
commit 1083dc460033b34f18d794faa34ec6ab512efa56
Author: Eli Zaretskii
Date: Sat Apr 16 19:27:25 2022 +0300
; * lisp/language/indian.el ("Brahmi"): Enhance composition rules.
diff --git a/lisp/language/indian.el b/lisp/language/indian.el
index 310905534e..0a50dd999f 100644
--- a/lisp/language/indian.el
+++ b/lisp/language/indian.el
@@ -396,7 +396,8 @@ The ancient Brahmi script is supported in this language environment."))
;; Brahmi composition rules
(let ((consonant "[\U00011013-\U00011034]")
- (non-consonant "[^\U00011013-\U00011034]")
+ (non-consonant "[^\U00011013-\U00011034\U00011046\U0001107F]")
+ (vowel "[\U00011038-\U0001103D\U00011042-\U00011045]")
(numeral "[\U00011052-\U00011065]")
(multiplier "[\U00011064\U00011065]")
(virama "\U00011046")
@@ -405,7 +406,8 @@ The ancient Brahmi script is supported in this language environment."))
'(#x11046 . #x11046)
(list (vector
;; Consonant conjuncts
- (concat consonant virama consonant)
+ (concat consonant "\\(?:" virama consonant "\\)+"
+ vowel "?")
1 'font-shape-gstring)
(vector
;; Vowelless consonants
commit 6bfb6fdb89463a2260de75479aa58f4254e2042f
Author: Lars Ingebrigtsen
Date: Sat Apr 16 18:08:42 2022 +0200
Fold some too-long NEWS lines
diff --git a/etc/NEWS b/etc/NEWS
index b1db06bd1d..bd2545f4be 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -586,10 +586,10 @@ change the terminal used on a remote host.
---
*** New user options for alternate wheel events.
-The options 'mouse-wheel-down-alternate-event', 'mouse-wheel-up-alternate-event',
-'mouse-wheel-left-alternate-event', and 'mouse-wheel-right-alternate-event' have
-been added to better support systems where two kinds of wheel events can be
-received.
+The options 'mouse-wheel-down-alternate-event',
+'mouse-wheel-up-alternate-event', 'mouse-wheel-left-alternate-event',
+and 'mouse-wheel-right-alternate-event' have been added to better
+support systems where two kinds of wheel events can be received.
** Editing complex text layout (CTL) scripts
@@ -702,7 +702,9 @@ bot doesn't exit the minibuffer.
** Isearch and Replace
+++
-*** New user option 'char-fold-override' disables default character equivalences.
+*** New user option 'char-fold-override'.
+Non-nil means that the default definitions of equivalent characters
+are overridden.
+++
*** New command 'isearch-emoji-by-name'.
@@ -1726,7 +1728,7 @@ Specifying a cons as the FROM argument allows to start measuring text
from a specified amount of pixels above or below a position.
---
-** 'eshell-eval-using-options' now follows POSIX/GNU argument syntax conventions.
+** 'eshell-eval-using-options' now follows argument syntax conventions.
Built-in commands in Eshell now accept command-line options with
values passed as a single token, such as '-oVALUE' or '--option=VALUE'.
commit e1137098277ca1dca8235d9146ef2c6d23d7417e
Author: Lars Ingebrigtsen
Date: Sat Apr 16 17:59:05 2022 +0200
Do some NEWS tagging
diff --git a/etc/NEWS b/etc/NEWS
index 64a52aeceb..b1db06bd1d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -58,6 +58,7 @@ The file is typically installed using a file name akin to
If a constant file name is required, the file can be renamed to
"emacs.pdmp", and Emacs will find it during startup anyway.
+---
** Emacs now supports use of XInput 2 for input events.
If your X server has support and you have the XInput 2 development headers
installed, you can configure Emacs with the option '--with-xinput2' to enable
@@ -557,6 +558,7 @@ effectively dragged.
Customize this option to limit the number of entries in the menu
"Edit->Paste from Kill Menu". The default is 60.
++++
** Performing a pinch gesture on a touchpad now increases the text scale.
** show-paren-mode
commit d5a715177c2dd505ed63cc337ef44323610bb9ea
Author: Lars Ingebrigtsen
Date: Sat Apr 16 17:38:37 2022 +0200
Do some NEWS tagging
diff --git a/etc/NEWS b/etc/NEWS
index c66d05eb93..64a52aeceb 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1194,6 +1194,7 @@ the Galeon web browser was released in September, 2008.
** Ruby Mode
+---
*** New user option 'ruby-toggle-block-space-before-parameters'.
** Eshell
@@ -1289,6 +1290,7 @@ they will still be escaped, so the '.foo' symbol is still printed as
and remapping parent of basic faces does not work reliably.
Instead of remapping 'mode-line', you have to remap 'mode-line-active'.
+---
** User option 'mail-source-ignore-errors' is now obsolete.
The whole mechanism for prompting users to continue in case of
mail-source errors has been removed, so this option is no longer
commit 52de048389f7c0a49a6a721697af41b4b57c2eea
Author: Lars Ingebrigtsen
Date: Sat Apr 16 17:35:44 2022 +0200
Improve exif-field discoverability
* lisp/image/exif.el (exif-parse-file, exif-parse-buffer): Link to
`exif-field'.
diff --git a/etc/NEWS b/etc/NEWS
index c177121c80..c66d05eb93 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1114,6 +1114,7 @@ the buffer will take you to that directory.
** Exif
+---
*** New function 'exif-field'.
This is a convenience function to extract the field data from
'exif-parse-file' and 'exif-parse-buffer'.
diff --git a/lisp/image/exif.el b/lisp/image/exif.el
index 35666b954c..fd4673dc1b 100644
--- a/lisp/image/exif.el
+++ b/lisp/image/exif.el
@@ -100,7 +100,10 @@ mirrored or not.")
"Parse FILE (a JPEG file) and return the Exif data, if any.
The return value is a list of Exif items.
-If the data is invalid, an `exif-error' is signaled."
+If the data is invalid, an `exif-error' is signaled.
+
+Also see the `exif-field' convenience function to extract data
+from the return value of this function."
(with-temp-buffer
(set-buffer-multibyte nil)
(insert-file-contents-literally file)
@@ -110,7 +113,10 @@ If the data is invalid, an `exif-error' is signaled."
"Parse BUFFER (which should be a JPEG file) and return the Exif data, if any.
The return value is a list of Exif items.
-If the data is invalid, an `exif-error' is signaled."
+If the data is invalid, an `exif-error' is signaled.
+
+Also see the `exif-field' convenience function to extract data
+from the return value of this function."
(setq buffer (or buffer (current-buffer)))
(with-current-buffer buffer
(if enable-multibyte-characters
commit 1c1c7b1b5b759067638323e036b770108a70f262
Author: Lars Ingebrigtsen
Date: Sat Apr 16 17:33:19 2022 +0200
Do some NEWS tagging
diff --git a/etc/NEWS b/etc/NEWS
index e24a46da45..c177121c80 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -978,6 +978,7 @@ The keybinding for 'image-transform-fit-to-width' is now 's i'.
*** User option 'image-auto-resize' can now be set to 'fit-window'.
This works like 'image-transform-fit-to-window'.
+---
*** New user option 'image-auto-resize-max-scale-percent'.
The new 'fit-window' option will never scale an image more than this
much (in percent). It is nil by default, which means no limit.
@@ -1097,6 +1098,7 @@ If non-nil, dragging file names with the mouse in a Dired buffer will
initiate a drag-and-drop session allowing them to be opened in other
programs.
++++
*** New user option 'dired-free-space'.
Dired will now, by default, include the free space in the first line
instead of having it on a separate line. To get the previous behavior
commit d5b9b1a9132fe3bc8f05356a76a9d2d65d2c1251
Author: Lars Ingebrigtsen
Date: Sat Apr 16 17:30:32 2022 +0200
Document project-kill-buffers-display-buffer-list
* doc/emacs/maintaining.texi (Project Buffer Commands): Mention
project-kill-buffers-display-buffer-list.
* lisp/progmodes/project.el (project-kill-buffers): Link to
project-kill-buffers-display-buffer-list.
diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi
index 7f3e9f45c2..fc2b2a24e2 100644
--- a/doc/emacs/maintaining.texi
+++ b/doc/emacs/maintaining.texi
@@ -1834,11 +1834,14 @@ buffers as candidates for completion.
@findex project-kill-buffers
@vindex project-kill-buffer-conditions
+@vindex project-kill-buffers-display-buffer-list
When you finish working on the project, you may wish to kill all the
buffers that belong to the project, to keep your Emacs session
smaller. The command @kbd{C-x p k} (@code{project-kill-buffers})
accomplishes that: it kills all the buffers that belong to the current
-project that satisfy any of @code{project-kill-buffer-conditions}.
+project that satisfy any of @code{project-kill-buffer-conditions}. If
+@code{project-kill-buffers-display-buffer-list} is non-@code{nil}, the
+buffers to be killed will be displayed first.
@node Switching Projects
@subsection Switching Projects
diff --git a/etc/NEWS b/etc/NEWS
index 1965270db6..e24a46da45 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -927,6 +927,7 @@ it with new 'term-{faint,italic,slow-blink,fast-blink}' faces.
*** 'project-find-file' and 'project-or-external-find-file' now accept
a prefix argument which is interpreted to mean "include all files".
++++
*** 'project-kill-buffers' can display the list of buffers to kill.
Customize the user option 'project-kill-buffers-display-buffer-list'
to enable the display of the buffer list.
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index ac6aa0ced2..369c425bb1 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -1330,7 +1330,9 @@ identical. Only the buffers that match a condition in
`project-kill-buffer-conditions' will be killed. If NO-CONFIRM
is non-nil, the command will not ask the user for confirmation.
NO-CONFIRM is always nil when the command is invoked
-interactively."
+interactively.
+
+Also see the `project-kill-buffers-display-buffer-list' variable."
(interactive)
(let* ((pr (project-current t))
(bufs (project--buffers-to-kill pr))
commit 35c4f6c609cd36ff77c0303591a4da77e51ba3d1
Author: Lars Ingebrigtsen
Date: Sat Apr 16 17:27:37 2022 +0200
Document prefix to project-find-file
* doc/emacs/maintaining.texi (Project File Commands): Mention the
prefix in the project-find-file command.
diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi
index 37c348d54a..7f3e9f45c2 100644
--- a/doc/emacs/maintaining.texi
+++ b/doc/emacs/maintaining.texi
@@ -1728,6 +1728,7 @@ doesn't seem to belong to a recognizable project, these commands
prompt you for the project directory.
@findex project-find-file
+@vindex vc-directory-exclusion-list
The command @kbd{C-x p f} (@code{project-find-file}) is a convenient
way of visiting files (@pxref{Visiting}) that belong to the current
project. Unlike @kbd{C-x C-f}, this command doesn't require to type
@@ -1736,7 +1737,9 @@ base name (i.e., omit the leading directories). In addition, the
completion candidates considered by the command include only the files
belonging to the current project, and nothing else. If there's a file
name at point, this command offers that file as the first element of
-the ``future history''.
+the ``future history''. If given a prefix, include all files under
+the project root, except for @acronym{VCS} directories listed in
+@code{vc-directory-exclusion-list}.
@findex project-find-regexp
The command @kbd{C-x p g} (@code{project-find-regexp}) is similar to
diff --git a/etc/NEWS b/etc/NEWS
index a2028e1aca..1965270db6 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -886,6 +886,7 @@ default, no automatic renaming is performed.
** Help
+---
*** New user option 'help-link-key-to-documentation'.
When this option is non-nil (which is the default), key bindings
displayed in the "*Help*" buffer will be linked to the documentation
@@ -922,6 +923,7 @@ it with new 'term-{faint,italic,slow-blink,fast-blink}' faces.
** Xref
++++
*** 'project-find-file' and 'project-or-external-find-file' now accept
a prefix argument which is interpreted to mean "include all files".
commit bb8e277df1b03ad05be7cbb8c8458d3df4da03f2
Author: Lars Ingebrigtsen
Date: Sat Apr 16 17:21:43 2022 +0200
Fix glyphless-display-mode indexing
* doc/lispref/display.texi (Glyphless Chars): Fix indexing.
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 2dc0ef4c0b..cbd8ac9b9a 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -8281,7 +8281,7 @@ there is no available font (on a graphical display), and characters
which cannot be encoded by the terminal's coding system (on a text
terminal).
-@vindex glyphless-display-mode
+@findex glyphless-display-mode
The @code{glyphless-display-mode} minor mode can be used to toggle
displaying glyphless characters in a convenient manner in the current
buffer. If this mode is enabled, all the glyphless characters are
diff --git a/etc/NEWS b/etc/NEWS
index 4b8b3d4d6f..a2028e1aca 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -691,6 +691,7 @@ When this user option names a face, the current
candidate in the "*Completions*" buffer is highlighted with that face.
The nil value disables this highlighting.
+---
*** Choosing a completion with a prefix argument doesn't exit the minibuffer.
This means that typing 'C-u RET' on a completion candidate in the
"*Completions*" buffer inserts the completion to the minibuffer,
@@ -708,6 +709,7 @@ command accepts the Unicode name of an Emoji (for example, "smiling
face" or "heart with arrow"), like 'C-x 8 e e', with minibuffer
completion, and adds the Emoji into the search string.
++++
** New minor mode 'glyphless-display-mode'.
This allows an easy way to toggle seeing all glyphless characters in
the current buffer.
commit a1954288de9dc9f88f8b77a4a7c3685b5ebc96b6
Author: Lars Ingebrigtsen
Date: Sat Apr 16 17:20:04 2022 +0200
Document completions-sort
* doc/emacs/mini.texi (Completion Options): Document completions-sort.
diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi
index 52856d7137..6012d2f280 100644
--- a/doc/emacs/mini.texi
+++ b/doc/emacs/mini.texi
@@ -690,6 +690,12 @@ changed by changing the @code{completions-format} user option. If
@code{vertical}, sort the completions vertically in columns instead,
and if @code{one-column}, just use a single column.
+@vindex completions-sort
+ This user option controls how completions are sorted in the
+@samp{*Completions*} buffer. The default is @code{alphabetical}, but
+it can also be a function which will be called with the list of
+completions, and should return the list in the desired order.
+
@vindex completions-max-height
When @code{completions-max-height} is non-@code{nil}, it limits the
size of the completions window. It is specified in lines and include
diff --git a/etc/NEWS b/etc/NEWS
index 45d88a5cb1..4b8b3d4d6f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -659,6 +659,7 @@ When non-nil, the commands 'next-completion' and 'previous-completion'
automatically wrap around on reaching the beginning or the end of
the "*Completions*" buffer.
++++
*** New user option 'completions-sort'.
This option controls the sorting of the completion candidates in
the "*Completions*" buffer. Available styles are no sorting,
commit db1bfcd9091d7765cbc1990d26802ecf013f6772
Author: Lars Ingebrigtsen
Date: Sat Apr 16 17:17:05 2022 +0200
Mention completion-wrap-movement in relevant commands
* lisp/simple.el (previous-completion, next-completion): Mention
`completion-wrap-movement'.
diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi
index eebe284b09..52856d7137 100644
--- a/doc/emacs/mini.texi
+++ b/doc/emacs/mini.texi
@@ -381,6 +381,8 @@ used with the completion list:
@vindex minibuffer-completion-auto-choose
@item M-
@itemx @key{M-}
+@findex previous-completion
+@findex next-completion
These keys will navigate through the completions displayed in the
completions buffer. When @code{minibuffer-completion-auto-choose} is
non-@code{nil} (which is the default), using these commands will
diff --git a/etc/NEWS b/etc/NEWS
index 35bb3987e6..45d88a5cb1 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -653,6 +653,7 @@ To enable this behavior, customize the user option
'second-tab', then the first 'TAB' will display "*Completions*", and
the second one will switch to the "*Completions*" buffer.
+---
*** New user option 'completion-wrap-movement'.
When non-nil, the commands 'next-completion' and 'previous-completion'
automatically wrap around on reaching the beginning or the end of
diff --git a/lisp/simple.el b/lisp/simple.el
index 2481d22ad1..bbab57703d 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -9208,14 +9208,18 @@ the completions is popped up and down."
(defun previous-completion (n)
"Move to the previous item in the completion list.
With prefix argument N, move back N items (negative N means move
-forward)."
+forward).
+
+Also see the `completion-wrap-movement' variable."
(interactive "p")
(next-completion (- n)))
(defun next-completion (n)
"Move to the next item in the completion list.
With prefix argument N, move N items (negative N means move
-backward)."
+backward).
+
+Also see the `completion-wrap-movement' variable."
(interactive "p")
(let ((prev (previous-single-property-change (point) 'mouse-face)))
(goto-char (cond
commit 429f2c4b81d44702e4d4513a7eb2dbada867279a
Author: Lars Ingebrigtsen
Date: Sat Apr 16 17:14:08 2022 +0200
Document minibuffer-completion-auto-choose/M-up/M-down
* doc/emacs/mini.texi (Completion Commands): Document
minibuffer-completion-auto-choose/M-up/M-down.
diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi
index eeb87972cc..eebe284b09 100644
--- a/doc/emacs/mini.texi
+++ b/doc/emacs/mini.texi
@@ -378,6 +378,20 @@ window. You can display the same list with @kbd{?}
used with the completion list:
@table @kbd
+@vindex minibuffer-completion-auto-choose
+@item M-
+@itemx @key{M-}
+These keys will navigate through the completions displayed in the
+completions buffer. When @code{minibuffer-completion-auto-choose} is
+non-@code{nil} (which is the default), using these commands will
+automatically insert the current completion candidate in the
+minibuffer. If this user option is @code{nil}, the keys will navigate
+the same way as before, but won't automatically insert the candidate
+in the minibuffer. Instead you have to use the @key{M-RET} command to
+do that. With a prefix argument, @key{C-u M-RET} inserts the
+currently active candidate to the minibuffer, but doesn't exit the
+minibuffer.
+
@findex switch-to-completions
@item M-v
@itemx @key{PageUp}
diff --git a/etc/NEWS b/etc/NEWS
index e9a420e92d..35bb3987e6 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -632,6 +632,7 @@ value.
** Minibuffer and Completions
++++
*** New commands for navigating completions from the minibuffer.
When the minibuffer is the current buffer, typing 'M-' or
'M-' selects a previous/next completion candidate from the
commit 37b11e5f169f03cc5c8ee63b797b848dabd8f0e8
Author: Lars Ingebrigtsen
Date: Sat Apr 16 17:02:01 2022 +0200
Further IDNA/proxy url fixes
* lisp/url/url-http.el (url-http-create-request): Puny-encode
domains (bug#54921).
diff --git a/lisp/url/url-http.el b/lisp/url/url-http.el
index 96a4742956..b5bcd123c7 100644
--- a/lisp/url/url-http.el
+++ b/lisp/url/url-http.el
@@ -332,7 +332,10 @@ Use `url-http-referer' as the Referer-header (subject to `url-privacy-level')."
(if (and using-proxy
;; Bug#35969.
(not (equal "https" (url-type url-http-target-url))))
- (url-recreate-url url-http-target-url) real-fname))
+ (let ((url (copy-sequence url-http-target-url)))
+ (setf (url-host url) (puny-encode-domain (url-host url)))
+ (url-recreate-url url))
+ real-fname))
" HTTP/" url-http-version "\r\n"
;; Version of MIME we speak
"MIME-Version: 1.0\r\n"
commit 51013d328c36668410e03d55060059576e286a98
Author: Lars Ingebrigtsen
Date: Sat Apr 16 16:59:41 2022 +0200
Crosslink some buttonize function doc strings
* lisp/button.el (buttonize-region, buttonize): Crosslink doc
strings for discoverability.
diff --git a/lisp/button.el b/lisp/button.el
index 797ef12031..244201be2d 100644
--- a/lisp/button.el
+++ b/lisp/button.el
@@ -620,7 +620,9 @@ When clicked, CALLBACK will be called with the DATA as the
function argument. If DATA isn't present (or is nil), the button
itself will be used instead as the function argument.
-If HELP-ECHO, use that as the `help-echo' property."
+If HELP-ECHO, use that as the `help-echo' property.
+
+Also see `buttonize-region'."
(apply #'propertize string
(button--properties callback data help-echo)))
@@ -642,7 +644,9 @@ When clicked, CALLBACK will be called with the DATA as the
function argument. If DATA isn't present (or is nil), the button
itself will be used instead as the function argument.
-If HELP-ECHO, use that as the `help-echo' property."
+If HELP-ECHO, use that as the `help-echo' property.
+
+Also see `buttonize'."
(add-text-properties start end (button--properties callback data help-echo)))
(provide 'button)
commit d1bc95b3a4ab4ddfcb8c97104e1a2dbb306ea515
Author: Lars Ingebrigtsen
Date: Sat Apr 16 16:35:57 2022 +0200
Improve completion in `C-h R'
* lisp/info.el (info-display-manual): Use it (bug#54961).
(info--filter-manual-names): Filter away duplicates and irrelevant
files.
diff --git a/lisp/info.el b/lisp/info.el
index db95574bf7..ac4169b550 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -5440,7 +5440,8 @@ completion alternatives to currently visited manuals."
(progn
(info-initialize)
(completing-read "Manual name: "
- (info--manual-names current-prefix-arg)
+ (info--filter-manual-names
+ (info--manual-names current-prefix-arg))
nil t))))
(let ((blist (buffer-list))
(manual-re (concat "\\(/\\|\\`\\)" manual "\\(\\.\\|\\'\\)"))
@@ -5468,6 +5469,22 @@ completion alternatives to currently visited manuals."
(info (Info-find-file manual)
(generate-new-buffer-name "*info*")))))
+(defun info--filter-manual-names (names)
+ (cl-flet ((strip (name)
+ (replace-regexp-in-string "\\([-.]info\\)?\\(\\.gz\\)?\\'"
+ "" name)))
+ (seq-uniq (sort (seq-filter
+ (lambda (name)
+ (and (not (string-match-p "info-[0-9]" name))
+ (not (member name '("./" "../" "ChangeLog"
+ "NEWS" "README")))))
+ names)
+ ;; We prefer the shorter names ("foo" over "foo.gz").
+ (lambda (s1 s2)
+ (< (length s1) (length s2))))
+ (lambda (s1 s2)
+ (equal (strip s1) (strip s2))))))
+
(defun info--manual-names (visited-only)
(let (names)
(dolist (buffer (buffer-list))
commit 1c495aff71fc798b7b9663c3a35055badafded97 (refs/remotes/origin/emacs-28)
Author: Lars Ingebrigtsen
Date: Sat Apr 16 16:24:39 2022 +0200
Clarify when mode tagging is used
* etc/NEWS: Clarify when mode tagging is used (bug#54964).
diff --git a/etc/NEWS b/etc/NEWS
index 7fb8e8dce8..4996029199 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -3240,12 +3240,13 @@ completing on commands from buffers in major modes derived from
MODE..., or, if it's a minor mode, when that minor mode is enabled in
the current buffer.
-Note that these forms will only have their effect if the
+Note that these forms will only have their effect for 'M-x' if the
'read-extended-command-predicate' user option is customized to call
'command-completion-default-include-p' or a similar function. The
default value of 'read-extended-command-predicate' is nil, which means
no commands that match what you have typed are excluded from being
-completion candidates.
+completion candidates. The forms will, however, be used by 'M-S-x' by
+default.
** 'define-minor-mode' now takes an ':interactive' argument.
This can be used for specifying which modes this minor mode is meant
commit d53c999b4ad7bc1f730875ae3d1af9d11895807c
Author: Lars Ingebrigtsen
Date: Thu Apr 14 16:51:39 2022 +0200
Further vcs-cvs/rcs-responsible-p updates from master
* lisp/vc/vc-bzr.el (vc-bzr-responsible-p):
* lisp/vc/vc-sccs.el (vc-sccs-responsible-p):
* lisp/vc/vc-dav.el (vc-dav-responsible-p): Update doc string.
* lisp/vc/vc-rcs.el (vc-rcs-responsible-p):
* lisp/vc/vc-cvs.el (vc-cvs-responsible-p): Further fixes from
master.
* lisp/vc/vc-src.el (vc-src-responsible-p): Return the directory.
* lisp/vc/vc.el: Update comments.
diff --git a/lisp/vc/vc-bzr.el b/lisp/vc/vc-bzr.el
index 836630acb5..ee394a93af 100644
--- a/lisp/vc/vc-bzr.el
+++ b/lisp/vc/vc-bzr.el
@@ -640,7 +640,7 @@ Returns nil if unable to find this information."
;; Could run `bzr status' in the directory and see if it succeeds, but
;; that's relatively expensive.
(defalias 'vc-bzr-responsible-p #'vc-bzr-root
- "Return non-nil if FILE is (potentially) controlled by bzr.
+ "Return the directory if FILE is (potentially) controlled by bzr.
The criterion is that there is a `.bzr' directory in the same
or a superior directory.")
diff --git a/lisp/vc/vc-cvs.el b/lisp/vc/vc-cvs.el
index e4524db951..8f06d5a847 100644
--- a/lisp/vc/vc-cvs.el
+++ b/lisp/vc/vc-cvs.el
@@ -308,12 +308,12 @@ to the CVS command."
(vc-switches 'CVS 'register)))
(defun vc-cvs-responsible-p (file)
- "Return non-nil if CVS thinks it is responsible for FILE."
+ "Return the directory if CVS thinks it is responsible for FILE."
(let ((dir (if (file-directory-p file)
file
(file-name-directory file))))
(and (file-directory-p (expand-file-name "CVS" dir))
- dir)))
+ (file-name-directory (expand-file-name "CVS" dir)))))
(defun vc-cvs-could-register (file)
"Return non-nil if FILE could be registered in CVS.
diff --git a/lisp/vc/vc-dav.el b/lisp/vc/vc-dav.el
index 61e2cd2390..94621599e4 100644
--- a/lisp/vc/vc-dav.el
+++ b/lisp/vc/vc-dav.el
@@ -137,9 +137,9 @@ It should return a status of either 0 (no differences found), or
)
(defun vc-dav-responsible-p (url)
- "Return non-nil if DAV considers itself `responsible' for URL."
+ "Return the URL if DAV considers itself `responsible' for URL."
;; Check for DAV support on the web server.
- (and t url))
+ url)
;;; Unimplemented functions
;;
diff --git a/lisp/vc/vc-rcs.el b/lisp/vc/vc-rcs.el
index dc6f3c8915..fb57b2bbc6 100644
--- a/lisp/vc/vc-rcs.el
+++ b/lisp/vc/vc-rcs.el
@@ -288,13 +288,13 @@ to the RCS command."
(match-string 1))))))
(defun vc-rcs-responsible-p (file)
- "Return non-nil if RCS thinks it would be responsible for registering FILE."
+ "Return the directory if RCS thinks it would be responsible for FILE."
;; TODO: check for all the patterns in vc-rcs-master-templates
(let ((dir (if (file-directory-p file)
file
(file-name-directory file))))
(and (file-directory-p (expand-file-name "RCS" dir))
- dir)))
+ (file-name-directory (expand-file-name "RCS" dir)))))
(defun vc-rcs-receive-file (file rev)
"Implementation of receive-file for RCS."
diff --git a/lisp/vc/vc-sccs.el b/lisp/vc/vc-sccs.el
index ef64cd9d58..0df70c8f23 100644
--- a/lisp/vc/vc-sccs.el
+++ b/lisp/vc/vc-sccs.el
@@ -212,7 +212,7 @@ to the SCCS command."
(vc-sccs-do-command nil 0 "get" (vc-master-name file)))))
(defun vc-sccs-responsible-p (file)
- "Return non-nil if SCCS thinks it would be responsible for registering FILE."
+ "Return the directory if SCCS thinks it would be responsible for FILE."
;; TODO: check for all the patterns in vc-sccs-master-templates
(or (and (file-directory-p
(expand-file-name "SCCS" (file-name-directory file)))
diff --git a/lisp/vc/vc-src.el b/lisp/vc/vc-src.el
index 1c1a7b5d13..5a252c55cb 100644
--- a/lisp/vc/vc-src.el
+++ b/lisp/vc/vc-src.el
@@ -242,11 +242,13 @@ This function differs from vc-do-command in that it invokes `vc-src-program'."
(vc-src-command nil files "add"))
(defun vc-src-responsible-p (file)
- "Return non-nil if SRC thinks it would be responsible for registering FILE."
- (file-directory-p (expand-file-name ".src"
- (if (file-directory-p file)
- file
- (file-name-directory file)))))
+ "Return the directory if SRC thinks it would be responsible for FILE."
+ (let ((dir (expand-file-name ".src"
+ (if (file-directory-p file)
+ file
+ (file-name-directory file)))))
+ (and (file-directory-p dir)
+ dir)))
(defun vc-src-checkin (files comment &optional _rev)
"SRC-specific version of `vc-backend-checkin'.
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index 45c09ae1c6..bebd0946de 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -220,7 +220,7 @@
;;
;; - responsible-p (file)
;;
-;; Return non-nil if this backend considers itself "responsible" for
+;; Return the directory if this backend considers itself "responsible" for
;; FILE, which can also be a directory. This function is used to find
;; out what backend to use for registration of new files and for things
;; like change log generation. The default implementation always
commit 4f1612188b331be0a5caeb8d3cb7a8aec9392dab
Author: Lars Ingebrigtsen
Date: Sat Apr 16 16:11:45 2022 +0200
Make emacs-news-next-untagged-entry push the mark
* lisp/textmodes/emacs-news-mode.el
(emacs-news-next-untagged-entry): Push the mark for easier
navigation back to where we were.
diff --git a/lisp/textmodes/emacs-news-mode.el b/lisp/textmodes/emacs-news-mode.el
index 88b4740ac8..340187e5fd 100644
--- a/lisp/textmodes/emacs-news-mode.el
+++ b/lisp/textmodes/emacs-news-mode.el
@@ -107,6 +107,7 @@
(setq found t))))))
(if found
(progn
+ (push-mark start)
(message "Untagged entry")
(beginning-of-line)
t)
commit 5752a839e59a2159203f7665b9a5ab740250b1ab
Author: Lars Ingebrigtsen
Date: Sat Apr 16 16:07:25 2022 +0200
Fix NEWS tag commands
* lisp/textmodes/emacs-news-mode.el
(emacs-news-next-untagged-entry): Fix logic.
(emacs-news-count-untagged-entries): Add new command and keystroke.
diff --git a/lisp/textmodes/emacs-news-mode.el b/lisp/textmodes/emacs-news-mode.el
index b56cf13adb..88b4740ac8 100644
--- a/lisp/textmodes/emacs-news-mode.el
+++ b/lisp/textmodes/emacs-news-mode.el
@@ -40,7 +40,8 @@
:version "29.1")
(defvar-keymap emacs-news-mode-map
- "C-c C-s" #'emacs-news-next-untagged-entry)
+ "C-c C-s" #'emacs-news-next-untagged-entry
+ "C-c C-n" #'emacs-news-count-untagged-entries)
(defvar emacs-news-mode-font-lock-keywords
`(("^---$" 0 'emacs-news-does-not-need-documentation)
@@ -91,25 +92,39 @@
;; progress if calling this command repeatedly.
(forward-line 1)
(while (and (not found)
- (re-search-forward "\\(\\*+\\) " nil t)
- (not (save-excursion
- (forward-line -1)
- (looking-at "---$\\|\\+\\+\\+$"))))
- ;; We have an entry without a tag before it, but check whether
- ;; it's a heading (which we can determine if the next entry has
- ;; more asterisks).
- (let ((level (length (match-string 1))))
- (when (save-excursion
- (re-search-forward "^\\(\\*+\\) " nil t))
- (when (<= (length (match-string 1)) level)
- ;; It wasn't a sub-heading, so we've found one.
- (setq found t)))))
+ (re-search-forward "\\(\\*+\\) " nil t))
+ (unless (save-excursion
+ (forward-line -1)
+ (looking-at "---$\\|\\+\\+\\+$"))
+ ;; We have an entry without a tag before it, but check whether
+ ;; it's a heading (which we can determine if the next entry has
+ ;; more asterisks).
+ (let ((level (length (match-string 1))))
+ (when (save-excursion
+ (re-search-forward "^\\(\\*+\\) " nil t))
+ (when (<= (length (match-string 1)) level)
+ ;; It wasn't a sub-heading, so we've found one.
+ (setq found t))))))
(if found
(progn
(message "Untagged entry")
- (beginning-of-line))
+ (beginning-of-line)
+ t)
(message "No further untagged entries")
- (goto-char start))))
+ (goto-char start)
+ nil)))
+
+(defun emacs-news-count-untagged-entries ()
+ "Say how many untagged entries there are in the current NEWS buffer."
+ (interactive nil emacs-news-mode)
+ (save-excursion
+ (goto-char (point-min))
+ (let ((i 0))
+ (while (emacs-news-next-untagged-entry)
+ (setq i (1+ i)))
+ (message (if (= i 1)
+ "There's 1 untagged entry"
+ (format "There's %s untagged entries" i))))))
(defun emacs-news--buttonize ()
"Make manual and symbol references into buttons."
commit db416ae04982d7cf5c6af463d0c47c902f8d9119
Author: Lars Ingebrigtsen
Date: Sat Apr 16 15:58:20 2022 +0200
Clean up emacs-news--buttonize
* lisp/textmodes/emacs-news-mode.el (emacs-news--buttonize):
Remove unnecessary check left over from previous version.
diff --git a/lisp/textmodes/emacs-news-mode.el b/lisp/textmodes/emacs-news-mode.el
index 5099a7435f..b56cf13adb 100644
--- a/lisp/textmodes/emacs-news-mode.el
+++ b/lisp/textmodes/emacs-news-mode.el
@@ -122,14 +122,13 @@
(while (re-search-forward "'\\([^-][^ \t\n]+\\)'" nil t)
;; Filter out references to key sequences.
(let ((string (match-string 1)))
- (unless (key-valid-p string)
- (when-let ((symbol (intern-soft string)))
- (when (or (boundp symbol)
- (fboundp symbol))
- (buttonize-region (match-beginning 1) (match-end 1)
- (lambda (symbol)
- (describe-symbol symbol))
- symbol))))))
+ (when-let ((symbol (intern-soft string)))
+ (when (or (boundp symbol)
+ (fboundp symbol))
+ (buttonize-region (match-beginning 1) (match-end 1)
+ (lambda (symbol)
+ (describe-symbol symbol))
+ symbol)))))
;; Do manual references.
(goto-char (point-min))
(search-forward "\f" nil t)
commit b381929c9150376e1bc722aa309a9626ef3b394b
Author: Lars Ingebrigtsen
Date: Sat Apr 16 15:57:33 2022 +0200
Bind TAB and on buttons
* lisp/button.el (button-map): Inherit from 'button-buffer-map'.
diff --git a/etc/NEWS b/etc/NEWS
index 72b1309cef..e9a420e92d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -123,6 +123,13 @@ of 'user-emacs-directory'.
* Incompatible changes in Emacs 29.1
+---
+** 'TAB' and '' is now bound in 'button-map'.
+This means that if you're standing on a button, 'TAB' will take you to
+the next button, even if the mode has bound it to something else.
+This also means that 'TAB' on a button in an 'outline-minor-mode'
+heading will move point instead of collapsing the outline.
+
---
** 'Info-default-directory-list' is no longer populated at Emacs startup.
If you have code in your init file that removes directories from
diff --git a/lisp/button.el b/lisp/button.el
index 86cf4a9ae5..797ef12031 100644
--- a/lisp/button.el
+++ b/lisp/button.el
@@ -55,29 +55,24 @@
"Default face used for buttons."
:group 'basic-faces)
-(defvar button-map
- (let ((map (make-sparse-keymap)))
- ;; The following definition needs to avoid using escape sequences that
- ;; might get converted to ^M when building loaddefs.el
- (define-key map [(control ?m)] 'push-button)
- (define-key map [mouse-2] 'push-button)
- (define-key map [follow-link] 'mouse-face)
- ;; FIXME: You'd think that for keymaps coming from text-properties on the
- ;; mode-line or header-line, the `mode-line' or `header-line' prefix
- ;; shouldn't be necessary!
- (define-key map [mode-line mouse-2] 'push-button)
- (define-key map [header-line mouse-2] 'push-button)
- map)
- "Keymap used by buttons.")
-
-(defvar button-buffer-map
- (let ((map (make-sparse-keymap)))
- (define-key map [?\t] 'forward-button)
- (define-key map "\e\t" 'backward-button)
- (define-key map [backtab] 'backward-button)
- map)
- "Keymap useful for buffers containing buttons.
-Mode-specific keymaps may want to use this as their parent keymap.")
+(defvar-keymap button-buffer-map
+ :doc "Keymap useful for buffers containing buttons.
+Mode-specific keymaps may want to use this as their parent keymap."
+ "TAB" #'forward-button
+ "C-TAB" #'backward-button
+ "" #'backward-button)
+
+(defvar-keymap button-map
+ :doc "Keymap used by buttons."
+ :parent button-buffer-map
+ "RET" #'push-button
+ "" #'push-button
+ "" 'mouse-face
+ ;; FIXME: You'd think that for keymaps coming from text-properties on the
+ ;; mode-line or header-line, the `mode-line' or `header-line' prefix
+ ;; shouldn't be necessary!
+ " " #'push-button
+ " " #'push-button)
(define-minor-mode button-mode
"A minor mode for navigating to buttons with the TAB key."
commit dcbef9045f0d5427470d660d240d1e6d5cf97663
Author: Lars Ingebrigtsen
Date: Sat Apr 16 15:40:57 2022 +0200
Regenerated ldefs-boot.el
diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el
index cb2da55ed2..e03535483a 100644
--- a/lisp/ldefs-boot.el
+++ b/lisp/ldefs-boot.el
@@ -10409,6 +10409,19 @@ some major modes from being locked under some circumstances.
(register-definition-prefixes "emacs-lock" '("emacs-lock-" "toggle-emacs-lock"))
+;;;***
+
+;;;### (autoloads nil "emacs-news-mode" "textmodes/emacs-news-mode.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from textmodes/emacs-news-mode.el
+
+(autoload 'emacs-news-mode "emacs-news-mode" "\
+Major mode for editing and viewind the Emacs NEWS file.
+
+\(fn)" t nil)
+
+(register-definition-prefixes "emacs-news-mode" '("emacs-news-"))
+
;;;***
;;;### (autoloads nil "emacsbug" "mail/emacsbug.el" (0 0 0 0))
commit 5a59059b240fa55c0c6832e6619305ae9b2b939c
Author: Lars Ingebrigtsen
Date: Sat Apr 16 15:40:43 2022 +0200
Add a new mode for editing and viewing the Emacs NEWS file
* etc/NEWS (mode): Use emacs-news-mode.
* lisp/help.el (view-emacs-news): Use emacs-news-mode.
* lisp/textmodes/emacs-news-mode.el: New mode for editing and
viewing the Emacs NEWS file.
diff --git a/etc/NEWS b/etc/NEWS
index c9f8ae4630..72b1309cef 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -603,6 +603,13 @@ script that was used in ancient South Asia.
* Changes in Specialized Modes and Packages in Emacs 29.1
+---
+** New mode for editing and viewing the NEWS file.
+It's called 'emacs-news-mode', and adds some highlighting, fixes the
+'M-q' command, and has commands for doing maintenance. When in read
+only mode (which you get when doing 'C-h N', for instance), it also
+adds buttons to manual entries and symbol references.
+
---
** kmacro
Kmacros are now OClosures and have a new constructor 'kmacro' which
@@ -1997,6 +2004,6 @@ along with GNU Emacs. If not, see .
Local variables:
coding: utf-8
-mode: outline
+mode: emacs-news
paragraph-separate: "[ ]*$"
end:
diff --git a/lisp/help.el b/lisp/help.el
index 780f5daac7..e326ea5d00 100644
--- a/lisp/help.el
+++ b/lisp/help.el
@@ -453,7 +453,9 @@ With argument, display info only for the selected version."
((< vn 18) "NEWS.1-17")
(t (format "NEWS.%d" vn))))
res)
- (view-file (expand-file-name file data-directory))
+ (find-file (expand-file-name file data-directory))
+ (setq buffer-read-only t)
+ (emacs-news-mode)
(widen)
(goto-char (point-min))
(when (stringp version)
diff --git a/lisp/textmodes/emacs-news-mode.el b/lisp/textmodes/emacs-news-mode.el
new file mode 100644
index 0000000000..5099a7435f
--- /dev/null
+++ b/lisp/textmodes/emacs-news-mode.el
@@ -0,0 +1,144 @@
+;;; emacs-news-mode.el --- major mode to edit and view the NEWS file -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2022 Free Software Foundation, Inc.
+
+;; Keywords: tools
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs 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.
+
+;; GNU Emacs 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 GNU Emacs. If not, see .
+
+;;; Commentary:
+
+;;; Code:
+
+(eval-when-compile (require 'cl-lib))
+
+(defgroup emacs-news-mode nil
+ "Major mode for editing and viewing the Emacs NEWS file."
+ :group 'lisp)
+
+(defface emacs-news-is-documented
+ '((t :inherit font-lock-type-face))
+ "Face used for displaying the \"is documented\" tag."
+ :version "29.1")
+
+(defface emacs-news-does-not-need-documentation
+ '((t :inherit font-lock-preprocessor-face))
+ "Face used for displaying the \"does not need documentation\" tag."
+ :version "29.1")
+
+(defvar-keymap emacs-news-mode-map
+ "C-c C-s" #'emacs-news-next-untagged-entry)
+
+(defvar emacs-news-mode-font-lock-keywords
+ `(("^---$" 0 'emacs-news-does-not-need-documentation)
+ ("^\\+\\+\\+$" 0 'emacs-news-is-documented)))
+
+;;;###autoload
+(define-derived-mode emacs-news-mode text-mode "NEWS"
+ "Major mode for editing and viewind the Emacs NEWS file."
+ (setq-local font-lock-defaults '(emacs-news-mode-font-lock-keywords t))
+ (setq-local outline-regexp "^\\*+ "
+ outline-minor-mode-cycle t
+ outline-minor-mode-highlight 'append)
+ (setq-local fill-paragraph-function #'emacs-news--fill-paragraph)
+ (outline-minor-mode 1)
+ (when buffer-read-only
+ (emacs-news--buttonize)
+ (button-mode)))
+
+(defun emacs-news--fill-paragraph (&optional justify)
+ (cond
+ ;; We're in a heading -- do nothing.
+ ((save-excursion
+ (beginning-of-line)
+ (looking-at "\\*+ "))
+ )
+ ;; We're in a news item -- exclude the heading before filling.
+ ((and (save-excursion
+ (re-search-backward (concat "^\\(?:" paragraph-start "\\|\\*+ \\)")
+ nil t))
+ (= (char-after (match-beginning 0)) ?*))
+ (save-restriction
+ (narrow-to-region (save-excursion
+ (goto-char (match-beginning 0))
+ (forward-line 1)
+ (point))
+ (point-max))
+ (fill-paragraph justify)))
+ ;; Fill normally.
+ (t
+ (fill-paragraph justify))))
+
+(defun emacs-news-next-untagged-entry ()
+ "Go to the next untagged NEWS entry."
+ (interactive nil emacs-news-mode)
+ (let ((start (point))
+ (found nil))
+ ;; Don't consider the current line, because that would stop
+ ;; progress if calling this command repeatedly.
+ (forward-line 1)
+ (while (and (not found)
+ (re-search-forward "\\(\\*+\\) " nil t)
+ (not (save-excursion
+ (forward-line -1)
+ (looking-at "---$\\|\\+\\+\\+$"))))
+ ;; We have an entry without a tag before it, but check whether
+ ;; it's a heading (which we can determine if the next entry has
+ ;; more asterisks).
+ (let ((level (length (match-string 1))))
+ (when (save-excursion
+ (re-search-forward "^\\(\\*+\\) " nil t))
+ (when (<= (length (match-string 1)) level)
+ ;; It wasn't a sub-heading, so we've found one.
+ (setq found t)))))
+ (if found
+ (progn
+ (message "Untagged entry")
+ (beginning-of-line))
+ (message "No further untagged entries")
+ (goto-char start))))
+
+(defun emacs-news--buttonize ()
+ "Make manual and symbol references into buttons."
+ (save-excursion
+ (with-silent-modifications
+ (let ((inhibit-read-only t))
+ ;; Do functions and variables.
+ (goto-char (point-min))
+ (search-forward "\f" nil t)
+ (while (re-search-forward "'\\([^-][^ \t\n]+\\)'" nil t)
+ ;; Filter out references to key sequences.
+ (let ((string (match-string 1)))
+ (unless (key-valid-p string)
+ (when-let ((symbol (intern-soft string)))
+ (when (or (boundp symbol)
+ (fboundp symbol))
+ (buttonize-region (match-beginning 1) (match-end 1)
+ (lambda (symbol)
+ (describe-symbol symbol))
+ symbol))))))
+ ;; Do manual references.
+ (goto-char (point-min))
+ (search-forward "\f" nil t)
+ (while (re-search-forward "\"\\(([a-z0-9]+)[ \n][^\"]\\{1,80\\}\\)\""
+ nil t)
+ (buttonize-region (match-beginning 1) (match-end 1)
+ (lambda (node) (info node))
+ (match-string 1)))))))
+
+(provide 'emacs-news-mode)
+
+;;; emacs-news-mode.el ends here
commit d71ee07852f15738b63d5cd9c5ccecd88a84a35a
Author: Lars Ingebrigtsen
Date: Sat Apr 16 15:39:03 2022 +0200
Add new function buttonize-region
* lisp/button.el (buttonize-region): New function.
(button--properties): Factored out.
(buttonize): Use it.
diff --git a/etc/NEWS b/etc/NEWS
index 6913f159c0..c9f8ae4630 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1377,6 +1377,10 @@ functions.
* Lisp Changes in Emacs 29.1
++++
+** New convenience function 'buttonize-region'.
+This works like 'buttonize', but for a region instead of a string.
+
+++
** 'macroexp-let2*' can omit 'test' arg and use single-var bindings.
diff --git a/lisp/button.el b/lisp/button.el
index 8a7751d00d..86cf4a9ae5 100644
--- a/lisp/button.el
+++ b/lisp/button.el
@@ -626,16 +626,29 @@ function argument. If DATA isn't present (or is nil), the button
itself will be used instead as the function argument.
If HELP-ECHO, use that as the `help-echo' property."
- (propertize string
- 'face 'button
- 'mouse-face 'highlight
- 'help-echo help-echo
- 'button t
- 'follow-link t
- 'category t
- 'button-data data
- 'keymap button-map
- 'action callback))
+ (apply #'propertize string
+ (button--properties callback data help-echo)))
+
+(defun button--properties (callback data help-echo)
+ (list 'face 'button
+ 'font-lock-face 'button
+ 'mouse-face 'highlight
+ 'help-echo help-echo
+ 'button t
+ 'follow-link t
+ 'category t
+ 'button-data data
+ 'keymap button-map
+ 'action callback))
+
+(defun buttonize-region (start end callback &optional data help-echo)
+ "Make the region between START and END into a button.
+When clicked, CALLBACK will be called with the DATA as the
+function argument. If DATA isn't present (or is nil), the button
+itself will be used instead as the function argument.
+
+If HELP-ECHO, use that as the `help-echo' property."
+ (add-text-properties start end (button--properties callback data help-echo)))
(provide 'button)
commit 5ad6a08a2eb5a57520f0c954a76c19f28d00ae9d
Author: Po Lu
Date: Sat Apr 16 19:12:04 2022 +0800
Prevent race conditions with async input during drag-and-drop
* src/xterm.c (XTread_socket): Don't read events here during
drag-and-drop, otherwise the right hold_quit might not be used
for selection events.
diff --git a/src/xterm.c b/src/xterm.c
index dc33ba7556..b65de88674 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -18968,6 +18968,13 @@ XTread_socket (struct terminal *terminal, struct input_event *hold_quit)
bool event_found = false;
struct x_display_info *dpyinfo = terminal->display_info.x;
+ /* Don't allow XTread_socket to do anything if drag-and-drop is in
+ progress. If unblock_input causes XTread_socket to be called and
+ read X events while the drag-and-drop event loop is in progress,
+ things can go wrong very quick. */
+ if (x_dnd_in_progress || x_dnd_waiting_for_finish)
+ return 0;
+
block_input ();
/* For debugging, this gives a way to fake an I/O error. */
commit 6815db492ff899e77b45be98414567ad96a8177c
Author: Mattias Engdegård
Date: Sat Apr 16 11:33:14 2022 +0200
Fix builds on older versions of macOS
This adds back macOS-specific code replaced earlier (bug#48548),
specifically to fix build errors on macOS 10.7.5. See discussion at
https://lists.gnu.org/archive/html/emacs-devel/2022-04/msg00779.html .
* src/sysdep.c (HAVE_RUSAGE_INFO_CURRENT, HAVE_PROC_PIDINFO): New.
(system_process_attributes): Use alternative code or exclude features
when building on older macOS versions.
(cherry picked from commit 855e15dbf10a6aac42b860fdb28711f979e2bf22)
diff --git a/src/sysdep.c b/src/sysdep.c
index 1632f46d13..87a6365de6 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -4012,6 +4012,9 @@ system_process_attributes (Lisp_Object pid)
#elif defined DARWIN_OS
+#define HAVE_RUSAGE_INFO_CURRENT (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101000)
+#define HAVE_PROC_PIDINFO (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)
+
Lisp_Object
system_process_attributes (Lisp_Object pid)
{
@@ -4114,6 +4117,7 @@ system_process_attributes (Lisp_Object pid)
attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (proc.kp_eproc.e_tpgid)),
attrs);
+#if HAVE_RUSAGE_INFO_CURRENT
rusage_info_current ri;
if (proc_pid_rusage(proc_id, RUSAGE_INFO_CURRENT, (rusage_info_t *) &ri) == 0)
{
@@ -4127,6 +4131,22 @@ system_process_attributes (Lisp_Object pid)
attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (ri.ri_pageins)), attrs);
}
+#else /* !HAVE_RUSAGE_INFO_CURRENT */
+ struct rusage *rusage = proc.kp_proc.p_ru;
+ if (rusage)
+ {
+ attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (rusage->ru_minflt)),
+ attrs);
+ attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (rusage->ru_majflt)),
+ attrs);
+
+ Lisp_Object utime = make_lisp_timeval (rusage->ru_utime);
+ Lisp_Object stime = make_lisp_timeval (rusage->ru_stime);
+ attrs = Fcons (Fcons (Qutime, utime), attrs);
+ attrs = Fcons (Fcons (Qstime, stime), attrs);
+ attrs = Fcons (Fcons (Qtime, Ftime_add (utime, stime)), attrs);
+ }
+#endif /* !HAVE_RUSAGE_INFO_CURRENT */
starttime = proc.kp_proc.p_starttime;
attrs = Fcons (Fcons (Qnice, make_fixnum (proc.kp_proc.p_nice)), attrs);
@@ -4137,6 +4157,7 @@ system_process_attributes (Lisp_Object pid)
Lisp_Object etime = Ftime_convert (Ftime_subtract (now, start), Qnil);
attrs = Fcons (Fcons (Qetime, etime), attrs);
+#if HAVE_PROC_PIDINFO
struct proc_taskinfo taskinfo;
if (proc_pidinfo (proc_id, PROC_PIDTASKINFO, 0, &taskinfo, sizeof (taskinfo)) > 0)
{
@@ -4144,6 +4165,7 @@ system_process_attributes (Lisp_Object pid)
attrs = Fcons (Fcons (Qrss, make_fixnum (taskinfo.pti_resident_size / 1024)), attrs);
attrs = Fcons (Fcons (Qthcount, make_fixnum (taskinfo.pti_threadnum)), attrs);
}
+#endif /* HAVE_PROC_PIDINFO */
#ifdef KERN_PROCARGS2
char args[ARG_MAX];
commit 16ccca6dc38aefb8c000560f8cf4cdc5f46b0727
Author: Eli Zaretskii
Date: Sat Apr 16 13:18:47 2022 +0300
Improve support for the Brahmi script
* lisp/language/indian.el ("Brahmi"): New language environment.
Add composition rules for Brahmi.
* lisp/international/fontset.el (script-representative-chars)
(setup-default-fontset): Support Brahmi. (Bug#54914)
* etc/NEWS: Announce the new language environment.
diff --git a/etc/NEWS b/etc/NEWS
index 14d970fe11..6913f159c0 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -596,6 +596,10 @@ to edit such sequences by allowing point to "enter" the sequence.
*** New language environment "Northern Thai".
This uses the Tai Tham script, whose support has been enhanced.
+*** New language environment "Brahmi".
+This language environment supports Brahmi, which is a historical
+script that was used in ancient South Asia.
+
* Changes in Specialized Modes and Packages in Emacs 29.1
diff --git a/lisp/international/fontset.el b/lisp/international/fontset.el
index 1950a40935..883f08905e 100644
--- a/lisp/international/fontset.el
+++ b/lisp/international/fontset.el
@@ -231,6 +231,7 @@
(chorasmian #x10FB0)
(elymaic #x10FE0)
(old-uyghur #x10F70)
+ (brahmi #x11013 #x11045 #x11052 #x11065)
(mahajani #x11150)
(khojki #x11200)
(khudawadi #x112B0)
@@ -770,6 +771,7 @@
chorasmian
elymaic
old-uyghur
+ brahmi
makasar
dives-akuru
cuneiform
diff --git a/lisp/language/indian.el b/lisp/language/indian.el
index e0adb0de6c..310905534e 100644
--- a/lisp/language/indian.el
+++ b/lisp/language/indian.el
@@ -126,6 +126,16 @@ environment."))
South Indian language Malayalam is supported in this language environment."))
'("Indian"))
+(set-language-info-alist
+ "Brahmi" '((charset unicode)
+ (coding-system utf-8)
+ (coding-priority utf-8)
+ ; (input-method . "brahmi") ; FIXME
+ (documentation . "\
+The ancient Brahmi script is supported in this language environment."))
+ '("Indian")) ; Should we have an "Old" category?
+
+
;; Replace mnemonic characters in REGEXP according to TABLE. TABLE is
;; an alist of (MNEMONIC-STRING . REPLACEMENT-STRING).
@@ -384,6 +394,30 @@ South Indian language Malayalam is supported in this language environment."))
(list (vector (cdr slot) 0 #'font-shape-gstring))))))
char-script-table))
+;; Brahmi composition rules
+(let ((consonant "[\U00011013-\U00011034]")
+ (non-consonant "[^\U00011013-\U00011034]")
+ (numeral "[\U00011052-\U00011065]")
+ (multiplier "[\U00011064\U00011065]")
+ (virama "\U00011046")
+ (number-joiner "\U0001107F"))
+ (set-char-table-range composition-function-table
+ '(#x11046 . #x11046)
+ (list (vector
+ ;; Consonant conjuncts
+ (concat consonant virama consonant)
+ 1 'font-shape-gstring)
+ (vector
+ ;; Vowelless consonants
+ (concat consonant virama non-consonant)
+ 1 'font-shape-gstring)))
+ (set-char-table-range composition-function-table
+ '(#x1107F . #x1107F)
+ (list (vector
+ ;; Additive-multiplicative numerals
+ (concat multiplier number-joiner numeral)
+ 1 'font-shape-gstring))))
+
(provide 'indian)
;;; indian.el ends here
commit dc3d1628ecd7c0090c07480606e921a1f8f348a9
Author: Mattias Engdegård
Date: Sat Apr 16 12:16:45 2022 +0200
; * src/sysdep.c: Fix mistake in previous commit
diff --git a/src/sysdep.c b/src/sysdep.c
index f6d7d3920b..72be25f661 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -4027,8 +4027,8 @@ system_process_attributes (Lisp_Object pid)
#elif defined DARWIN_OS
-#define HAVE_RUSAGE_INFO_CURRENT (MAC_OS_X_VERSION_MIN_REQUIRED >= 101000)
-#define HAVE_PROC_PIDINFO (MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)
+#define HAVE_RUSAGE_INFO_CURRENT (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101000)
+#define HAVE_PROC_PIDINFO (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)
Lisp_Object
system_process_attributes (Lisp_Object pid)
commit 855e15dbf10a6aac42b860fdb28711f979e2bf22
Author: Mattias Engdegård
Date: Sat Apr 16 11:33:14 2022 +0200
Fix builds on older versions of macOS
This adds back macOS-specific code replaced earlier (bug#48548),
specifically to fix build errors on macOS 10.7.5. See discussion at
https://lists.gnu.org/archive/html/emacs-devel/2022-04/msg00779.html .
* src/sysdep.c (HAVE_RUSAGE_INFO_CURRENT, HAVE_PROC_PIDINFO): New.
(system_process_attributes): Use alternative code or exclude features
when building on older macOS versions.
diff --git a/src/sysdep.c b/src/sysdep.c
index 1e630835ad..f6d7d3920b 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -4027,6 +4027,9 @@ system_process_attributes (Lisp_Object pid)
#elif defined DARWIN_OS
+#define HAVE_RUSAGE_INFO_CURRENT (MAC_OS_X_VERSION_MIN_REQUIRED >= 101000)
+#define HAVE_PROC_PIDINFO (MAC_OS_X_VERSION_MIN_REQUIRED >= 1050)
+
Lisp_Object
system_process_attributes (Lisp_Object pid)
{
@@ -4130,6 +4133,7 @@ system_process_attributes (Lisp_Object pid)
attrs = Fcons (Fcons (Qtpgid, INT_TO_INTEGER (proc.kp_eproc.e_tpgid)),
attrs);
+#if HAVE_RUSAGE_INFO_CURRENT
rusage_info_current ri;
if (proc_pid_rusage(proc_id, RUSAGE_INFO_CURRENT, (rusage_info_t *) &ri) == 0)
{
@@ -4143,6 +4147,24 @@ system_process_attributes (Lisp_Object pid)
attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (ri.ri_pageins)), attrs);
}
+#else /* !HAVE_RUSAGE_INFO_CURRENT */
+ struct rusage *rusage = proc.kp_proc.p_ru;
+ if (rusage)
+ {
+ attrs = Fcons (Fcons (Qminflt, INT_TO_INTEGER (rusage->ru_minflt)),
+ attrs);
+ attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (rusage->ru_majflt)),
+ attrs);
+
+ attrs = Fcons (Fcons (Qutime, make_lisp_timeval (rusage->ru_utime)),
+ attrs);
+ attrs = Fcons (Fcons (Qstime, make_lisp_timeval (rusage->ru_stime)),
+ attrs);
+ struct timespec t = timespec_add (timeval_to_timespec (rusage->ru_utime),
+ timeval_to_timespec (rusage->ru_stime));
+ attrs = Fcons (Fcons (Qtime, make_lisp_time (t)), attrs);
+ }
+#endif /* !HAVE_RUSAGE_INFO_CURRENT */
starttime = proc.kp_proc.p_starttime;
attrs = Fcons (Fcons (Qnice, make_fixnum (proc.kp_proc.p_nice)), attrs);
@@ -4152,6 +4174,7 @@ system_process_attributes (Lisp_Object pid)
t = timespec_sub (now, timeval_to_timespec (starttime));
attrs = Fcons (Fcons (Qetime, make_lisp_time (t)), attrs);
+#if HAVE_PROC_PIDINFO
struct proc_taskinfo taskinfo;
if (proc_pidinfo (proc_id, PROC_PIDTASKINFO, 0, &taskinfo, sizeof (taskinfo)) > 0)
{
@@ -4159,6 +4182,7 @@ system_process_attributes (Lisp_Object pid)
attrs = Fcons (Fcons (Qrss, make_fixnum (taskinfo.pti_resident_size / 1024)), attrs);
attrs = Fcons (Fcons (Qthcount, make_fixnum (taskinfo.pti_threadnum)), attrs);
}
+#endif /* HAVE_PROC_PIDINFO */
#ifdef KERN_PROCARGS2
char args[ARG_MAX];
commit de306d3e5dfecb336d5f66312e3e14ed8a27a81c
Author: Mattias Engdegård
Date: Sat Apr 16 11:31:58 2022 +0200
Disable annoying Clang warnings
* configure.ac (CHECK_LISP_OBJECT_TYPE): Disable
-Wimplicit-const-int-float-conversion and -Wint-in-bool-context, which
currently only have false positives.
diff --git a/configure.ac b/configure.ac
index 721cf16684..7c8638a471 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1105,6 +1105,8 @@ AS_IF([test $gl_gcc_warnings = no],
if test "$emacs_cv_clang" = yes; then
gl_WARN_ADD([-Wno-missing-braces])
gl_WARN_ADD([-Wno-null-pointer-arithmetic])
+ gl_WARN_ADD([-Wno-implicit-const-int-float-conversion])
+ gl_WARN_ADD([-Wno-int-in-bool-context])
fi
# This causes too much noise in the MinGW build
commit b3ff4905388834994ff26d9d033d6bc62b094c1c
Author: Lars Ingebrigtsen
Date: Sat Apr 16 11:21:25 2022 +0200
Fix ODF file detection in doc-view-mode
* lisp/doc-view.el (doc-view-set-doc-type): Fix ODF file detection
(bug#54947).
diff --git a/lisp/doc-view.el b/lisp/doc-view.el
index 5b07d75f6d..10adc9fcc9 100644
--- a/lisp/doc-view.el
+++ b/lisp/doc-view.el
@@ -1947,8 +1947,7 @@ If BACKWARD is non-nil, jump to the previous match."
;; zip-archives, so that this same association is used for
;; cbz files. This is fine, as cbz files should be handled
;; like epub anyway.
- ((looking-at "PK") '(epub))
- ))))
+ ((looking-at "PK") '(epub odf))))))
(setq-local
doc-view-doc-type
(car (or (nreverse (seq-intersection name-types content-types #'eq))
commit 625d6da5bad8c5e33d8c3214853d0bc35695f76d
Author: Po Lu
Date: Sat Apr 16 17:13:21 2022 +0800
Fix build with toolkit scroll bars without XI2
* src/xterm.c (mark_xterm): Fix up ifdefs slightly.
diff --git a/src/xterm.c b/src/xterm.c
index ae3f2d7517..dc33ba7556 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -23847,7 +23847,7 @@ void
mark_xterm (void)
{
Lisp_Object val;
-#ifdef HAVE_XINPUT2
+#if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS
struct x_display_info *dpyinfo;
int i;
#endif
commit 760107639be7657c4a209c9c04b17c79fc19f2c6
Author: Po Lu
Date: Sat Apr 16 16:48:02 2022 +0800
Protect windows from garbage collection when a ClientMessage is pending
* src/xterm.c (x_protect_window_for_callback)
(x_unprotect_window_for_callback): New functions.
(x_send_scroll_bar_event): Protect windows from garbage
collection before sending event containing pointer to window.
(handle_one_xevent): Unprotect after such a ClientMessage is
received and the window put in the keyboard buffer.
(x_term_init): Initialize protected windows list.
(x_delete_display): Free that list.
(mark_xterm): Mark the windows in that list.
* src/xterm.h (struct x_display_info): New fields for recording
a list of protected windows.
diff --git a/src/xterm.c b/src/xterm.c
index c5b31553ae..ae3f2d7517 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -10846,6 +10846,35 @@ xt_horizontal_action_hook (Widget widget, XtPointer client_data, String action_n
}
#endif /* not USE_GTK */
+/* Protect WINDOW from garbage collection until a matching scroll bar
+ message is received. Return whether or not protection
+ succeeded. */
+static bool
+x_protect_window_for_callback (struct x_display_info *dpyinfo,
+ Lisp_Object window)
+{
+ if (dpyinfo->n_protected_windows + 1
+ >= dpyinfo->protected_windows_max)
+ return false;
+
+ dpyinfo->protected_windows[dpyinfo->n_protected_windows++]
+ = window;
+ return true;
+}
+
+static void
+x_unprotect_window_for_callback (struct x_display_info *dpyinfo)
+{
+ if (!dpyinfo->n_protected_windows)
+ emacs_abort ();
+
+ dpyinfo->n_protected_windows--;
+
+ if (dpyinfo->n_protected_windows)
+ memmove (dpyinfo->protected_windows, &dpyinfo->protected_windows[1],
+ sizeof (Lisp_Object) * dpyinfo->n_protected_windows);
+}
+
/* Send a client message with message type Xatom_Scrollbar for a
scroll action to the frame of WINDOW. PART is a value identifying
the part of the scroll bar that was clicked on. PORTION is the
@@ -10863,8 +10892,12 @@ x_send_scroll_bar_event (Lisp_Object window, enum scroll_bar_part part,
verify (INTPTR_WIDTH <= 64);
int sign_shift = INTPTR_WIDTH - 32;
- block_input ();
+ /* Don't do anything if too many scroll bar events have been
+ sent but not received. */
+ if (!x_protect_window_for_callback (FRAME_DISPLAY_INFO (f), window))
+ return;
+ block_input ();
/* Construct a ClientMessage event to send to the frame. */
ev->type = ClientMessage;
ev->message_type = (horizontal
@@ -18854,6 +18887,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
count++;
}
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ if (event->xany.type == ClientMessage
+ && inev.ie.kind == SCROLL_BAR_CLICK_EVENT)
+ x_unprotect_window_for_callback (dpyinfo);
+#endif
+
if (do_help
&& !(hold_quit && hold_quit->kind != NO_EVENT))
{
@@ -23415,6 +23454,12 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
x_extension_initialize (dpyinfo);
#endif
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ dpyinfo->protected_windows = xmalloc (sizeof (Lisp_Object) * 256);
+ dpyinfo->n_protected_windows = 0;
+ dpyinfo->protected_windows_max = 256;
+#endif
+
unblock_input ();
return dpyinfo;
@@ -23469,12 +23514,14 @@ x_delete_display (struct x_display_info *dpyinfo)
xfree (dpyinfo->x_id_name);
xfree (dpyinfo->x_dnd_atoms);
xfree (dpyinfo->color_cells);
- xfree (dpyinfo);
-
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ xfree (dpyinfo->protected_windows);
+#endif
#ifdef HAVE_XINPUT2
if (dpyinfo->supports_xi2)
x_free_xi_devices (dpyinfo);
#endif
+ xfree (dpyinfo);
}
#ifdef USE_X_TOOLKIT
@@ -23817,11 +23864,17 @@ mark_xterm (void)
mark_object (val);
}
-#ifdef HAVE_XINPUT2
+#if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS
for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
{
+#ifdef HAVE_XINPUT2
for (i = 0; i < dpyinfo->num_devices; ++i)
mark_object (dpyinfo->devices[i].name);
+#endif
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ for (i = 0; i < dpyinfo->n_protected_windows; ++i)
+ mark_object (dpyinfo->protected_windows[i]);
+#endif
}
#endif
}
diff --git a/src/xterm.h b/src/xterm.h
index a04596cdb1..5d2b397874 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -672,6 +672,12 @@ struct x_display_info
int xshape_event_base;
int xshape_error_base;
#endif
+
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ Lisp_Object *protected_windows;
+ int n_protected_windows;
+ int protected_windows_max;
+#endif
};
#ifdef HAVE_X_I18N
commit 09f905c80b1b678152ed966a4a78edc07775aa00
Author: Eli Zaretskii
Date: Sat Apr 16 11:41:48 2022 +0300
; * lisp/window.el (display-buffer-assq-regexp): Doc fix.
diff --git a/lisp/window.el b/lisp/window.el
index ea90995541..f3a09ee462 100644
--- a/lisp/window.el
+++ b/lisp/window.el
@@ -7496,10 +7496,11 @@ all fail. It should never be set by programs or users. See
(put 'display-buffer-fallback-action 'risky-local-variable t)
(defun display-buffer-assq-regexp (buffer-or-name alist action)
- "Retrieve ALIST entry corresponding to BUFFER-NAME.
-This returns the cdr of the alist entry ALIST if key and
-buffer-or-name satisfy `buffer-match-p'. ACTION should have the
-form of the action argument passed to `display-buffer'."
+ "Retrieve ALIST entry corresponding to buffer specified by BUFFER-OR-NAME.
+This returns the cdr of the alist entry ALIST if the entry's
+key (its car) and BUFFER-OR-NAME satisfy `buffer-match-p', using
+the key as CONDITION argument of `buffer-match-p'. ACTION should
+have the form of the action argument passed to `display-buffer'."
(catch 'match
(dolist (entry alist)
(when (buffer-match-p (car entry) buffer-or-name action)
commit 9da744e45021648a37f175967b536b151fd18750
Author: Eli Zaretskii
Date: Sat Apr 16 10:56:01 2022 +0300
Fix documentation of Outline minor mode options
* lisp/outline.el (outline-minor-mode-cycle-filter)
(outline-minor-mode-cycle, outline-minor-mode-highlight)
(outline-cycle, outline-cycle-buffer): Doc fixes. (Bug#54967)
diff --git a/lisp/outline.el b/lisp/outline.el
index ac51b53de3..00a557ca4e 100644
--- a/lisp/outline.el
+++ b/lisp/outline.el
@@ -176,13 +176,22 @@ in the file it applies to.")
map))
(defcustom outline-minor-mode-cycle-filter nil
- "Filter out positions on the heading available for cycling."
+ "Control where on a heading the visibility-cycling commands are bound to keys.
+This option controls, in Outline minor mode, where on a heading typing
+the key sequences bound to visibility-cycling commands like `outline-cycle'
+and `outline-cycle-buffer' will invoke those commands. By default, you can
+invoke these commands by typing `TAB' and `S-TAB' anywhere on a heading line,
+but customizing this option can make those bindings be in effect only at
+specific positions on the heading, like only at the line's beginning or
+line's end. This allows these keys to be bound to their usual commands,
+as determined by the major mode, elsewhere on the heading lines.
+This option is only in effect when `outline-minor-mode-cycle' is non-nil."
:type '(choice (const :tag "Everywhere" nil)
(const :tag "At line beginning" bolp)
(const :tag "Not at line beginning"
(lambda () (not (bolp))))
(const :tag "At line end" eolp)
- (function :tag "Custom filter"))
+ (function :tag "Custom filter function"))
:version "28.1")
(defun outline-minor-mode-cycle--bind (map key binding &optional filter)
@@ -349,28 +358,33 @@ After that, changing the prefix key requires manipulating keymaps."
(set-default sym val)))
(defcustom outline-minor-mode-cycle nil
- "Enable cycling of headings in `outline-minor-mode'.
-When enabled, it puts a keymap with cycling keys on heading lines.
-When point is on a heading line, then typing `TAB' cycles between `hide all',
-`headings only' and `show all' (`outline-cycle'). Typing `S-TAB' on
-a heading line cycles the whole buffer (`outline-cycle-buffer').
-Typing these keys anywhere outside heading lines uses their default bindings."
+ "Enable visibility-cycling commands on headings in `outline-minor-mode'.
+If enabled, typing `TAB' on a heading line cycles the visibility
+state of that heading's body between `hide all', `headings only'
+and `show all' (`outline-cycle'), and typing `S-TAB' on a heading
+line likewise cycles the visibility state of the whole buffer
+\(`outline-cycle-buffer').
+Typing these keys anywhere outside heading lines invokes their default
+bindings, per the current major mode."
:type 'boolean
:version "28.1")
;;;###autoload(put 'outline-minor-mode-cycle 'safe-local-variable 'booleanp)
(defcustom outline-minor-mode-highlight nil
- "Highlight headings in `outline-minor-mode' using font-lock keywords.
-Non-nil value works well only when outline font-lock keywords
-don't conflict with the major mode's font-lock keywords.
-When t, it puts outline faces only if there are no major mode's faces
-on headings. When `override', it completely overwrites major mode's
-faces with outline faces. When `append', it tries to append outline
-faces to major mode's faces."
- :type '(choice (const :tag "No highlighting" nil)
- (const :tag "Overwrite major mode faces" override)
- (const :tag "Append outline faces to major mode faces" append)
- (const :tag "Highlight separately from major mode faces" t))
+ "Whether to highlight headings in `outline-minor-mode' using font-lock keywords.
+This option controles whether `outline-minor-mode' will use its font-lock
+keywords to highlight headings, which could potentially conflict with
+font-lock faces defined by the major mode. Thus, a non-nil value will
+work well only when there's no such conflict.
+If the value is t, use outline faces only if there are no major mode's
+font-lock faces on headings. When `override', completely overwrite major
+mode's font-lock faces with outline faces. When `append', try to append
+outline font-lock faces to those of major mode."
+ :type '(choice (const :tag "Do not use outline font-lock highlighting" nil)
+ (const :tag "Overwrite major mode font-lock faces" override)
+ (const :tag "Append outline font-lock faces to major mode's"
+ append)
+ (const :tag "Highlight with outline font-lock faces only if major mode doesn't" t))
:version "28.1")
;;;###autoload(put 'outline-minor-mode-highlight 'safe-local-variable 'symbolp)
@@ -1244,11 +1258,14 @@ Return either 'hide-all, 'headings-only, or 'show-all."
(save-excursion (outline-end-of-subtree) (point)))))
(defun outline-cycle ()
- "Cycle between `hide all', `headings only' and `show all'.
+ "Cycle visibility state of the current heading line's body.
-`Hide all' means hide all subheadings and their bodies.
-`Headings only' means show sub headings but not their bodies.
-`Show all' means show all subheadings and their bodies."
+This cycles the visibility of the current heading line's subheadings
+and body between `hide all', `headings only' and `show all'.
+
+`Hide all' means hide all the subheadings and their bodies.
+`Headings only' means show the subheadings, but not their bodies.
+`Show all' means show all the subheadings and their bodies."
(interactive)
(condition-case nil
(pcase (outline--cycle-state)
@@ -1270,7 +1287,15 @@ Return either 'hide-all, 'headings-only, or 'show-all."
"Internal variable used for tracking buffer cycle state.")
(defun outline-cycle-buffer ()
- "Cycle the whole buffer like in `outline-cycle'."
+ "Cycle visibility state of the body lines of the whole buffer.
+
+This cycles the visibility of all the subheadings and bodies of all
+the heading lines in the buffer. It cycles them between `hide all',
+`headings only' and `show all'.
+
+`Hide all' means hide all the buffer's subheadings and their bodies.
+`Headings only' means show all the subheadings, but not their bodies.
+`Show all' means show all the buffer's subheadings and their bodies."
(interactive)
(let (has-top-level)
(save-excursion
commit a8bb12ab054e063718687c0d8565ff9e7276585a
Author: Eli Zaretskii
Date: Fri Apr 15 23:03:15 2022 +0300
Improve discoverability of 'insert-directory-program'
* lisp/files.el (insert-directory-program): Mention 'dired' in the
doc string.
* lisp/dired.el (dired): Mention 'insert-directory-program' in the
doc string. (Bug#54962)
diff --git a/lisp/dired.el b/lisp/dired.el
index a3768d224b..f5ddd7aa39 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -994,8 +994,11 @@ If a directory or nothing is found at point, return nil."
;;;###autoload
(defun dired (dirname &optional switches)
"\"Edit\" directory DIRNAME--delete, rename, print, etc. some files in it.
-Optional second argument SWITCHES specifies the `ls' options used.
-\(Interactively, use a prefix argument to be able to specify SWITCHES.)
+Optional second argument SWITCHES specifies the options to be used
+when invoking `insert-directory-program', usually `ls', which produces
+the listing of the directory files and their attributes.
+Interactively, a prefix argument will cause the command to prompt
+for SWITCHES.
If DIRNAME is a string, Dired displays a list of files in DIRNAME (which
may also have shell wildcards appended to select certain files).
diff --git a/lisp/files.el b/lisp/files.el
index 5fa38e46af..d8e7989672 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -7236,7 +7236,9 @@ need to be passed verbatim to shell commands."
(defvar insert-directory-program (purecopy "ls")
- "Absolute or relative name of the `ls' program used by `insert-directory'.")
+ "Absolute or relative name of the `ls'-like program.
+This is used by `insert-directory' and `dired-insert-directory'
+\(thus, also by `dired').")
(defcustom directory-free-space-program (purecopy "df")
"Program to get the amount of free space on a file system.
commit 3f166bdf44f7a3c06ade0643995a870cfcc28677
Author: Eli Zaretskii
Date: Fri Apr 15 15:38:06 2022 +0300
; * etc/PROBLEMS: Describe MS-Windows issues with fonts. (Bug#54685)
diff --git a/etc/PROBLEMS b/etc/PROBLEMS
index 5e88f289c2..2a26dfaec4 100644
--- a/etc/PROBLEMS
+++ b/etc/PROBLEMS
@@ -1062,6 +1062,21 @@ modern fonts are used, such as Noto Emoji or Ebrima.
The solution is to switch to a configuration that uses HarfBuzz as its
shaping engine, where these problems don't exist.
+** On MS-Windows, selecting some fonts as the default font doesn't work.
+
+This can happen if you select font variants such as "Light" or "Thin"
+or "Semibold" or "Heavy", and some others. The APIs used by Emacs on
+Windows to enumerate fonts in a font family consider only 4 font
+variants to belong to the same family: Regular, Italic, Bold, and
+Bold-Italic. All the other variants aren't returned by those APIs
+when we request to list all the fonts in a family, and thus aren't
+considered by Emacs to belong to the family. So any font variant that
+is not one of those 4 will likely not work as expected; in most cases
+Emacs will select some other font instead.
+
+The only workaround is not to choose such font variants as the default
+font when running Emacs on MS-Windows.
+
* Internationalization problems
** M-{ does not work on a Spanish PC keyboard.
commit 803ac857eef1ab25488d0bf0c9460dd2d89bd5d1
Author: Eli Zaretskii
Date: Fri Apr 15 12:03:36 2022 +0300
Fix cursor motion under truncate-lines with Flymake fringe indicator
* src/indent.c (Fvertical_motion): Don't consider fringe bitmaps
as "images" for the purpose of vertical-motion logic dealing with
overshooting buffer positions. (Bug#54946)
diff --git a/src/indent.c b/src/indent.c
index 9f1a448a73..f5a2a078b9 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -2197,7 +2197,10 @@ whether or not it is currently displayed in some window. */)
}
else
it_overshoot_count =
- !(it.method == GET_FROM_IMAGE || it.method == GET_FROM_STRETCH);
+ /* If image_id is negative, it's a fringe bitmap, which by
+ definition doesn't affect display in the text area. */
+ !((it.method == GET_FROM_IMAGE && it.image_id >= 0)
+ || it.method == GET_FROM_STRETCH);
if (start_x_given)
{
commit bc636515884530f0cab6fa53b8cbce0aacbc5287
Author: Lars Ingebrigtsen
Date: Sun Nov 14 02:38:48 2021 +0100
Make all vc-*-responsible-p functions return a string
* lisp/vc/vc-sccs.el (vc-sccs-responsible-p):
* lisp/vc/vc-rcs.el (vc-rcs-responsible-p):
* lisp/vc/vc-dav.el (vc-dav-responsible-p):
* lisp/vc/vc-cvs.el (vc-cvs-responsible-p): Return a file name
instead of t when we get a match (which is what
vc-backend-for-registration expects) (bug#51800).
This fixes the regression reported in bug#54935.
Do not merge to master.
diff --git a/lisp/vc/vc-cvs.el b/lisp/vc/vc-cvs.el
index 559bb25d09..e4524db951 100644
--- a/lisp/vc/vc-cvs.el
+++ b/lisp/vc/vc-cvs.el
@@ -309,10 +309,11 @@ to the CVS command."
(defun vc-cvs-responsible-p (file)
"Return non-nil if CVS thinks it is responsible for FILE."
- (file-directory-p (expand-file-name "CVS"
- (if (file-directory-p file)
- file
- (file-name-directory file)))))
+ (let ((dir (if (file-directory-p file)
+ file
+ (file-name-directory file))))
+ (and (file-directory-p (expand-file-name "CVS" dir))
+ dir)))
(defun vc-cvs-could-register (file)
"Return non-nil if FILE could be registered in CVS.
diff --git a/lisp/vc/vc-dav.el b/lisp/vc/vc-dav.el
index 1cc447fe0f..61e2cd2390 100644
--- a/lisp/vc/vc-dav.el
+++ b/lisp/vc/vc-dav.el
@@ -136,10 +136,10 @@ It should return a status of either 0 (no differences found), or
"Find the version control state of all files in DIR in a fast way."
)
-(defun vc-dav-responsible-p (_url)
+(defun vc-dav-responsible-p (url)
"Return non-nil if DAV considers itself `responsible' for URL."
;; Check for DAV support on the web server.
- t)
+ (and t url))
;;; Unimplemented functions
;;
diff --git a/lisp/vc/vc-rcs.el b/lisp/vc/vc-rcs.el
index 4137ece8d6..dc6f3c8915 100644
--- a/lisp/vc/vc-rcs.el
+++ b/lisp/vc/vc-rcs.el
@@ -290,10 +290,11 @@ to the RCS command."
(defun vc-rcs-responsible-p (file)
"Return non-nil if RCS thinks it would be responsible for registering FILE."
;; TODO: check for all the patterns in vc-rcs-master-templates
- (file-directory-p (expand-file-name "RCS"
- (if (file-directory-p file)
- file
- (file-name-directory file)))))
+ (let ((dir (if (file-directory-p file)
+ file
+ (file-name-directory file))))
+ (and (file-directory-p (expand-file-name "RCS" dir))
+ dir)))
(defun vc-rcs-receive-file (file rev)
"Implementation of receive-file for RCS."
diff --git a/lisp/vc/vc-sccs.el b/lisp/vc/vc-sccs.el
index 2ca848dae1..ef64cd9d58 100644
--- a/lisp/vc/vc-sccs.el
+++ b/lisp/vc/vc-sccs.el
@@ -214,9 +214,13 @@ to the SCCS command."
(defun vc-sccs-responsible-p (file)
"Return non-nil if SCCS thinks it would be responsible for registering FILE."
;; TODO: check for all the patterns in vc-sccs-master-templates
- (or (file-directory-p (expand-file-name "SCCS" (file-name-directory file)))
- (stringp (vc-sccs-search-project-dir (or (file-name-directory file) "")
- (file-name-nondirectory file)))))
+ (or (and (file-directory-p
+ (expand-file-name "SCCS" (file-name-directory file)))
+ file)
+ (let ((dir (vc-sccs-search-project-dir (or (file-name-directory file) "")
+ (file-name-nondirectory file))))
+ (and (stringp dir)
+ dir))))
(defun vc-sccs-checkin (files comment &optional rev)
"SCCS-specific version of `vc-backend-checkin'."
commit b201823f631082d4f386304ee9ec24b0d85f5def
Author: Eli Zaretskii
Date: Thu Apr 14 09:17:01 2022 +0300
Describe problems with invoking Python on MS-Windows
* etc/PROBLEMS: Describe problems with running an inferior Python
interpreter due to the MS-Windows "App Execution Aliases" feature.
(Bug#54860)
diff --git a/etc/PROBLEMS b/etc/PROBLEMS
index e48ce5a8b0..5e88f289c2 100644
--- a/etc/PROBLEMS
+++ b/etc/PROBLEMS
@@ -651,6 +651,46 @@ And then rename the system's readline so that it won't be loaded:
See for more details on
installation.
+*** On MS-Windows, invoking "M-x run-python" signals an error.
+
+If the error says something like this:
+
+ Python was not found; run with arguments to install
+ from the Microsoft Store, or disable this shortcut
+ from Settings > Manage App Execution Aliases.
+
+ Process Python exited abnormally with code 49
+
+then this is due to the MS-Windows "feature" that is intended to
+encourage you to install the latest available Python version. It
+works by placing "fake" python.exe and python3.exe executables in a
+special directory, and having that directory on your Path _before_ the
+directory where the real Python executable is installed. That "fake"
+Python then decides whether to redirect you to the Microsoft Store or
+invoke the actual Python. The directory where Windows keeps those
+"fake" executables is under your Windows user's 'AppData' directory,
+typically 'C:\Users\\AppData\Local\Microsoft\WindowsApps', where
+"" is the user name of your Windows user.
+
+To solve this, you have several alternatives:
+
+ . Go to "Settings > Manage App Execution Aliases" and turn OFF the
+ aliases for python.exe and/or python3.exe. This will affect only
+ Python, and may require you to manage upgrades to your Python
+ installation manually, instead of being automatically prompted by
+ MS-Windows.
+ . Move the directory with the "fake" executables to the end of Path,
+ or at least after the directory where the real Python is
+ installed. Depending on the position in Path where you move it,
+ it will affect Python and/or other programs which Windows monitors
+ via the "App Execution Aliases" feature.
+ . Manually remove python.exe and/or python3.exe from the above
+ directory. Again, this affects only your Python installation.
+
+Whatever you do, you will need to restart Emacs to refresh its notion
+of the directory where python.exe/python3.exe lives, because that is
+recorded when Python mode is started.
+
*** Visiting files in some auto-mounted directories causes Emacs to print
'Error reading dir-locals: (file-error "Read error" "is a directory" ...'
commit 880f2734c95cec7ee6a9eec596e86543508415cd
Author: Eli Zaretskii
Date: Wed Apr 13 16:07:40 2022 +0300
A better fix for bug#54800
* lisp/calc/calc.el (calc-align-stack-window): Improve scrolling
when windows have non-integral dimensions.
diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el
index 2f9afa02af..171f771132 100644
--- a/lisp/calc/calc.el
+++ b/lisp/calc/calc.el
@@ -1815,7 +1815,7 @@ See calc-keypad for details."
(if win
(progn
(calc-cursor-stack-index 0)
- (vertical-motion (- 3 (window-height win)))
+ (vertical-motion (- 3 (window-height win 'floor)))
(set-window-start win (point)))))
(calc-cursor-stack-index 0)
(if (looking-at " *\\.$")
commit 5ee959aa8783689627a1553c678fd4d3720236c8
Author: Lars Ingebrigtsen
Date: Wed Apr 13 06:11:43 2022 +0200
Add a comment about cl-concatenate
* lisp/emacs-lisp/cl-extra.el (cl-concatenate): Add a comment.
diff --git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el
index fd94554ca1..8e38df43c8 100644
--- a/lisp/emacs-lisp/cl-extra.el
+++ b/lisp/emacs-lisp/cl-extra.el
@@ -553,6 +553,9 @@ too large if positive or too small if negative)."
,new)))))
(seq-subseq seq start end))
+;;; This isn't a defalias because autoloading defalises doesn't work
+;;; very well.
+
;;;###autoload
(defun cl-concatenate (type &rest sequences)
"Concatenate, into a sequence of type TYPE, the argument SEQUENCEs.
commit ab2b822b9bbac321ec061de349cf0166cc406fe7
Author: Lars Ingebrigtsen
Date: Wed Apr 13 06:07:32 2022 +0200
Revert "Make cl-concatenate an alias of seq-concatenate"
This reverts commit 78f76fe16e2737b40694f82af28d17a90a21ed7b.
The commit made calls to cl-concatenate bug out, since
autoloading defalises doesn't work very well (bug#54901).
diff --git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el
index ed9b1b7d83..fd94554ca1 100644
--- a/lisp/emacs-lisp/cl-extra.el
+++ b/lisp/emacs-lisp/cl-extra.el
@@ -554,9 +554,10 @@ too large if positive or too small if negative)."
(seq-subseq seq start end))
;;;###autoload
-(defalias 'cl-concatenate #'seq-concatenate
+(defun cl-concatenate (type &rest sequences)
"Concatenate, into a sequence of type TYPE, the argument SEQUENCEs.
-\n(fn TYPE SEQUENCE...)")
+\n(fn TYPE SEQUENCE...)"
+ (apply #'seq-concatenate type sequences))
;;; List functions.
commit 78e1640ad52a58ec53ddacf73a3e3a292d7833f1
Author: Eli Zaretskii
Date: Tue Apr 12 17:05:15 2022 +0300
Fix 'window-text-pixel-width' when starting from display property
* src/xdisp.c (Fwindow_text_pixel_size): Handle the case where
there's a display property at START, and move_it_to overshoots.
Do not merge to master. (Bug#54862)
diff --git a/src/xdisp.c b/src/xdisp.c
index 44f2536880..15bb5eefb5 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -10788,11 +10788,51 @@ include the height of any of these, if present, in the return value. */)
non-zero X coordinate. */
reseat_at_previous_visible_line_start (&it);
it.current_x = it.hpos = 0;
+
+ int start_x;
if (IT_CHARPOS (it) != start)
- move_it_to (&it, start, -1, -1, -1, MOVE_TO_POS);
+ {
+ void *it1data = NULL;
+ struct it it1;
+
+ SAVE_IT (it1, it, it1data);
+ move_it_to (&it, start, -1, -1, -1, MOVE_TO_POS);
+ /* We could have a display property at START, in which case
+ asking move_it_to to stop at START will overshoot and stop at
+ position after START. So we try again, stopping before
+ START, and account for the width of the last buffer position
+ manually. */
+ if (IT_CHARPOS (it) > start && start > BEGV)
+ {
+ ptrdiff_t it1pos = IT_CHARPOS (it1);
+ int it1_x = it1.current_x;
+
+ RESTORE_IT (&it, &it1, it1data);
+ /* If START - 1 is the beginning of screen line, move_it_to
+ will not move, so we need to use a lower-level
+ move_it_in_display_line subroutine, and tell it to move
+ just 1 pixel, so it stops at the next display element. */
+ if (start - 1 > it1pos)
+ move_it_to (&it, start - 1, -1, -1, -1, MOVE_TO_POS);
+ else
+ move_it_in_display_line (&it, start, it1_x + 1,
+ MOVE_TO_POS | MOVE_TO_X);
+ start_x = it.current_x;
+ /* If we didn't change our buffer position, the pixel width
+ of what's here was not yet accounted for; do it manually. */
+ if (IT_CHARPOS (it) == start - 1)
+ start_x += it.pixel_width;
+ }
+ else
+ {
+ start_x = it.current_x;
+ bidi_unshelve_cache (it1data, true);
+ }
+ }
+ else
+ start_x = it.current_x;
/* Now move to TO. */
- int start_x = it.current_x;
int move_op = MOVE_TO_POS | MOVE_TO_Y;
int to_x = -1;
it.current_y = start_y;
commit 5e47d6284bf184cb21acb1fb142ddb6eeea9c8ec
Author: Stefan Monnier
Date: Mon Apr 11 14:24:23 2022 -0400
* lisp/gnus/mm-encode.el (mm-default-file-encoding): Fix "when" arg
diff --git a/lisp/gnus/mm-encode.el b/lisp/gnus/mm-encode.el
index ead3bae219..39b1ad1f3b 100644
--- a/lisp/gnus/mm-encode.el
+++ b/lisp/gnus/mm-encode.el
@@ -99,7 +99,7 @@ This variable should never be set directly, but bound before a call to
;;;###autoload
(define-obsolete-function-alias 'mm-default-file-encoding
- #'mm-default-file-type "future") ;Old bad name.
+ #'mm-default-file-type "28.1") ;Old bad name.
;;;###autoload
(defun mm-default-file-type (file)
"Return a default content type for FILE."
commit e71c7a7c600bae3337de95d193dd106e9bfa2b4c
Author: Eli Zaretskii
Date: Mon Apr 11 14:31:04 2022 +0300
Fix default-directory of buffers visiting files in renamed directories
* lisp/dired-aux.el (dired-rename-file): Take note of whether FILE
is a directory before it is renamed, which makes it impossible to
determine if it was a directory.
(dired-rename-subdir, dired-rename-subdir-1): Revert to using
dired-in-this-tree-p instead of file-in-directory-p, for the
benefit of files that were renamed/removed, because
file-in-directory-p returns nil in those cases. (Bug#54838)
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 15f95eb579..57155ec26d 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1838,22 +1838,23 @@ rename them using `vc-rename-file'."
"Rename FILE to NEWNAME.
Signal a `file-already-exists' error if a file NEWNAME already exists
unless OK-IF-ALREADY-EXISTS is non-nil."
- (dired-handle-overwrite newname)
- (dired-maybe-create-dirs (file-name-directory newname))
- (if (and dired-vc-rename-file
- (vc-backend file)
- (ignore-errors (vc-responsible-backend newname)))
- (vc-rename-file file newname)
- ;; error is caught in -create-files
- (rename-file file newname ok-if-already-exists))
- ;; Silently rename the visited file of any buffer visiting this file.
- (and (get-file-buffer file)
- (with-current-buffer (get-file-buffer file)
- (set-visited-file-name newname nil t)))
- (dired-remove-file file)
- ;; See if it's an inserted subdir, and rename that, too.
- (when (file-directory-p file)
- (dired-rename-subdir file newname)))
+ (let ((file-is-dir-p (file-directory-p file)))
+ (dired-handle-overwrite newname)
+ (dired-maybe-create-dirs (file-name-directory newname))
+ (if (and dired-vc-rename-file
+ (vc-backend file)
+ (ignore-errors (vc-responsible-backend newname)))
+ (vc-rename-file file newname)
+ ;; error is caught in -create-files
+ (rename-file file newname ok-if-already-exists))
+ ;; Silently rename the visited file of any buffer visiting this file.
+ (and (get-file-buffer file)
+ (with-current-buffer (get-file-buffer file)
+ (set-visited-file-name newname nil t)))
+ (dired-remove-file file)
+ ;; See if it's an inserted subdir, and rename that, too.
+ (when file-is-dir-p
+ (dired-rename-subdir file newname))))
(defun dired-rename-subdir (from-dir to-dir)
(setq from-dir (file-name-as-directory from-dir)
@@ -1866,7 +1867,7 @@ unless OK-IF-ALREADY-EXISTS is non-nil."
(while blist
(with-current-buffer (car blist)
(if (and buffer-file-name
- (file-in-directory-p buffer-file-name expanded-from-dir))
+ (dired-in-this-tree-p buffer-file-name expanded-from-dir))
(let ((modflag (buffer-modified-p))
(to-file (replace-regexp-in-string
(concat "^" (regexp-quote from-dir))
@@ -1885,7 +1886,7 @@ unless OK-IF-ALREADY-EXISTS is non-nil."
(while alist
(setq elt (car alist)
alist (cdr alist))
- (if (file-in-directory-p (car elt) expanded-dir)
+ (if (dired-in-this-tree-p (car elt) expanded-dir)
;; ELT's subdir is affected by the rename
(dired-rename-subdir-2 elt dir to)))
(if (equal dir default-directory)
commit cccaa9c31de363bba5920031ecdb9db4ad3207ee
Author: Lars Ingebrigtsen
Date: Mon Apr 11 12:40:50 2022 +0200
Fix a kill-append regression
* lisp/simple.el (kill-append): Fix a regression when
kill-ring-max is zero (bug#54842).
diff --git a/lisp/simple.el b/lisp/simple.el
index a8ca9600af..b9cb957064 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -5183,7 +5183,7 @@ If `kill-append-merge-undo' is non-nil, remove the last undo
boundary in the current buffer."
(let ((cur (car kill-ring)))
(kill-new (if before-p (concat string cur) (concat cur string))
- (or (string= cur "")
+ (or (= (length cur) 0)
(null (get-text-property 0 'yank-handler cur)))))
(when (and kill-append-merge-undo (not buffer-read-only))
(let ((prev buffer-undo-list)
commit 33828e4818f28407e5425b021cd64ad505b25d91
Author: Eli Zaretskii
Date: Sun Apr 10 20:19:01 2022 +0300
* doc/misc/eww.texi (Advanced): Correct outdated info (bug#54839).
diff --git a/doc/misc/eww.texi b/doc/misc/eww.texi
index 248bd63e87..df1eb53c9d 100644
--- a/doc/misc/eww.texi
+++ b/doc/misc/eww.texi
@@ -310,9 +310,9 @@ state the directionality.
size or content. By customizing @code{shr-max-image-proportion} you
can set the maximal image proportion in relation to the window they
are displayed in. E.g., 0.7 means an image is allowed to take up 70%
-of the width and height. If Emacs supports image scaling (ImageMagick
-support required) then larger images are scaled down. You can block
-specific images completely by customizing @code{shr-blocked-images}.
+of the width and height. If Emacs supports image scaling, then larger
+images are scaled down. You can block specific images completely by
+customizing @code{shr-blocked-images}.
@vindex shr-inhibit-images
You can control image display by customizing
commit e8d2f40f41b09ec5e4b4eebe6441927e8d1dc434
Author: Eli Zaretskii
Date: Sun Apr 10 15:44:11 2022 +0300
Clean up the MSDOS port
* src/msdos.h (tcdrain): Redirect to '_dos_commit'.
(openat, fchmodat, futimens, utimensat): Add prototypes.
* msdos/sed1v2.inp (MAKE_PDUMPER_FINGERPRINT): Fix indentation, so
that Make won't consider this line a command.
($(etc)/DOC): Chdir back to ../src, since "make-docfile -d" leaves
us in a wrong directory.
* msdos/sedlibmk.inp (GL_GNULIB_GETRANDOM, GL_GNULIB_MEMMEM)
(GL_GNULIB_SIGDESCR_NP): Define to 1, to get the prototypes from
Gnulib headers.
diff --git a/msdos/sed1v2.inp b/msdos/sed1v2.inp
index e041e4e5b8..a79bf2eb71 100644
--- a/msdos/sed1v2.inp
+++ b/msdos/sed1v2.inp
@@ -179,6 +179,8 @@ s/ *@LIBXPM@//
/^PAXCTL_dumped *=/s/=.*$/=/
/^PAXCTL_notdumped *=/s/=.*$/=/
/^DUMPING *=/s/@DUMPING@/unexec/
+/^[ \t]*MAKE_PDUMPER_FINGERPRINT = *$/c\
+MAKE_PDUMPER_FINGERPRINT =
/^lisp\.mk:/,/^$/c\
lisp.mk: $(lispsource)/loadup.el\
@rm -f $@\
@@ -190,6 +192,10 @@ lisp.mk: $(lispsource)/loadup.el\
/^ [ ]*\$(AM_V_at)\$(libsrc)\/make-docfile -d/s!make-docfile!make-docfile -o $(etc)/DOC!
/ > \$(etc)\/DOC *$/s/ >.*$//
+/^\$(etc)\/DOC/,/^$/{
+ /^$/i\
+ cd ../src
+}
/^ [ ]*\$(AM_V_GLOBALS)\$(libsrc)\/make-docfile.*>.*globals.tmp/s!make-docfile!make-docfile -o globals.tmp!
/^ [ ]*\$(AM_V_GLOBALS)\$(libsrc)\/make-doc/s!>.*$!!
/^\$(libsrc)\/make-docfile\$(EXEEXT): /i\
@@ -255,4 +261,4 @@ s| -I\$(top_srcdir)/lib||
s| -I\. -I\$(srcdir)| -I.|
/^ *test "X/d
/\$(CC) -o \$@.tmp/s/\$@.tmp/\$@/
-/mv \$@.tmp \$@/d
\ No newline at end of file
+/mv \$@.tmp \$@/d
diff --git a/msdos/sedlibmk.inp b/msdos/sedlibmk.inp
index 59ebec9e75..e87cef5fff 100644
--- a/msdos/sedlibmk.inp
+++ b/msdos/sedlibmk.inp
@@ -180,11 +180,14 @@ s/@PACKAGE@/emacs/
/^GL_GNULIB_ENVIRON *=/s/@GL_GNULIB_ENVIRON@/1/
/^GL_GNULIB_FDATASYNC *=/s/@GL_GNULIB_FDATASYNC@/1/
/^GL_GNULIB_GETLOADAVG *=/s/@GL_GNULIB_GETLOADAVG@/1/
+/^GL_GNULIB_GETRANDOM *=/s/@GL_GNULIB_GETRANDOM@/1/
/^GL_GNULIB_UNISTD_H_GETOPT *=/s/@GL_GNULIB_UNISTD_H_GETOPT@/1/
+/^GL_GNULIB_MEMMEM *=/s/@GL_GNULIB_MEMMEM@/1/
/^GL_GNULIB_MEMRCHR *=/s/@GL_GNULIB_MEMRCHR@/1/
/^GL_GNULIB_MEMPCPY *=/s/@GL_GNULIB_MEMPCPY@/1/
/^GL_GNULIB_MKOSTEMP *=/s/@GL_GNULIB_MKOSTEMP@/1/
/^GL_GNULIB_MKTIME *=/s/@GL_GNULIB_MKTIME@/1/
+/^GL_GNULIB_SIGDESCR_NP *=/s/@GL_GNULIB_SIGDESCR_NP@/1/
/^GL_GNULIB_TIME_R *=/s/@GL_GNULIB_TIME_R@/1/
/^GL_GNULIB_TIMEGM *=/s/@GL_GNULIB_TIMEGM@/1/
/^GL_GNULIB_TIME_RZ *=/s/@GL_GNULIB_TIME_RZ@/1/
diff --git a/src/msdos.h b/src/msdos.h
index 7e57c7c110..24697bcf24 100644
--- a/src/msdos.h
+++ b/src/msdos.h
@@ -22,6 +22,10 @@ along with GNU Emacs. If not, see . */
#include
#include "termhooks.h" /* struct terminal */
+struct terminal;
+
+extern unsigned int _dos_commit(int);
+#define tcdrain(f) _dos_commit(f)
int dos_ttraw (struct tty_display_info *);
int dos_ttcooked (void);
@@ -57,6 +61,11 @@ ssize_t readlinkat (int, const char *, char *, size_t);
int fstatat (int, char const *, struct stat *, int);
int unsetenv (const char *);
int faccessat (int, const char *, int, int);
+int openat (int, const char *, int, int);
+int fchmodat (int, const char *, mode_t, int);
+int futimens (int, const struct timespec[2]);
+int utimensat (int, const char *, const struct timespec[2], int);
+
void msdos_fatal_signal (int);
void syms_of_msdos (void);
int pthread_sigmask (int, const sigset_t *, sigset_t *);
commit 338eda09d88d83d408c0bba1448b1c9eabad2d02
Author: Daniel Martín
Date: Sun Apr 10 14:31:36 2022 +0200
Fix typo in next-error-find-buffer-function
* lisp/simple.el (next-error-find-buffer-function): Fix typo
(bug#54830).
diff --git a/lisp/simple.el b/lisp/simple.el
index 1f606556b6..a8ca9600af 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -222,7 +222,7 @@ rejected, and the function returns nil."
(defcustom next-error-find-buffer-function #'ignore
"Function called to find a `next-error' capable buffer.
-This functions takes the same three arguments as the function
+This function takes the same three arguments as the function
`next-error-find-buffer', and should return the buffer to be
used by the subsequent invocation of the command `next-error'
and `previous-error'.
commit b385fd0b880059f74d5c1409a08a9e1292b86e70
Author: Lars Ingebrigtsen
Date: Sun Apr 10 13:48:46 2022 +0200
Revert "Make shell-resync-dirs handle whitespace in directory names"
This reverts commit 90e65c826fab2092ad2099d7763538194c93e021.
This change led to hangs (bug#54776).
Do not merge to master; it has been fixed in a more encompassing way there.
diff --git a/lisp/shell.el b/lisp/shell.el
index c9def1bb3f..f0115b90a5 100644
--- a/lisp/shell.el
+++ b/lisp/shell.el
@@ -1060,41 +1060,25 @@ command again."
(accept-process-output proc)
(goto-char pt)))
(goto-char pmark) (delete-char 1) ; remove the extra newline
- ;; That's the dirlist. Grab it & parse it.
- (let* ((dls (buffer-substring-no-properties
- (match-beginning 0) (1- (match-end 0))))
- (dlsl nil)
- (pos 0)
- (ds nil))
- ;; Split the dirlist into whitespace and non-whitespace chunks.
- ;; dlsl will be a reversed list of tokens.
- (while (string-match "\\(\\S-+\\|\\s-+\\)" dls pos)
- (push (match-string 1 dls) dlsl)
- (setq pos (match-end 1)))
-
- ;; Prepend trailing entries until they form an existing directory,
- ;; whitespace and all. Discard the next whitespace and repeat.
- (while dlsl
- (let ((newelt "")
- tem1 tem2)
- (while newelt
- ;; We need tem1 because we don't want to prepend
- ;; `comint-file-name-prefix' repeatedly into newelt via tem2.
- (setq tem1 (pop dlsl)
- tem2 (concat comint-file-name-prefix tem1 newelt))
- (cond ((file-directory-p tem2)
- (push tem2 ds)
- (when (string= " " (car dlsl))
- (pop dlsl))
- (setq newelt nil))
- (t
- (setq newelt (concat tem1 newelt)))))))
-
- (with-demoted-errors "Couldn't cd: %s"
- (shell-cd (car ds))
- (setq shell-dirstack (cdr ds)
- shell-last-dir (car shell-dirstack))
- (shell-dirstack-message))))
+ ;; That's the dirlist. grab it & parse it.
+ (let* ((dl (buffer-substring (match-beginning 2) (1- (match-end 2))))
+ (dl-len (length dl))
+ (ds '()) ; new dir stack
+ (i 0))
+ (while (< i dl-len)
+ ;; regexp = optional whitespace, (non-whitespace), optional whitespace
+ (string-match "\\s *\\(\\S +\\)\\s *" dl i) ; pick off next dir
+ (setq ds (cons (concat comint-file-name-prefix
+ (substring dl (match-beginning 1)
+ (match-end 1)))
+ ds))
+ (setq i (match-end 0)))
+ (let ((ds (nreverse ds)))
+ (with-demoted-errors "Couldn't cd: %s"
+ (shell-cd (car ds))
+ (setq shell-dirstack (cdr ds)
+ shell-last-dir (car shell-dirstack))
+ (shell-dirstack-message)))))
(if started-at-pmark (goto-char (marker-position pmark)))))
;; For your typing convenience:
commit 84a285772201d077274dfc932524bbdf0d56848a
Author: Eli Zaretskii
Date: Sat Apr 9 16:30:23 2022 +0300
Fix scrolling of the stack window in Calc
* lisp/calc/calc.el (calc-align-stack-window): Fix off-by-one
error in computing the window-start point. (Bug#54800)
diff --git a/lisp/calc/calc.el b/lisp/calc/calc.el
index 81677d78e7..2f9afa02af 100644
--- a/lisp/calc/calc.el
+++ b/lisp/calc/calc.el
@@ -1815,7 +1815,7 @@ See calc-keypad for details."
(if win
(progn
(calc-cursor-stack-index 0)
- (vertical-motion (- 2 (window-height win)))
+ (vertical-motion (- 3 (window-height win)))
(set-window-start win (point)))))
(calc-cursor-stack-index 0)
(if (looking-at " *\\.$")
commit 9dd44505b1dd3564deb8964372ab8a1d1021cb33
Author: Eli Zaretskii
Date: Sat Apr 9 12:17:49 2022 +0300
; * src/window.c (Fset_window_start): Clarify the effect of NOFORCE.
diff --git a/src/window.c b/src/window.c
index 1e7c26b82e..32e486f9f9 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1850,8 +1850,13 @@ Return POS. */)
DEFUN ("set-window-start", Fset_window_start, Sset_window_start, 2, 3, 0,
doc: /* Make display in WINDOW start at position POS in WINDOW's buffer.
WINDOW must be a live window and defaults to the selected one. Return
-POS. Optional third arg NOFORCE non-nil inhibits next redisplay from
-overriding motion of point in order to display at this exact start.
+POS.
+
+Optional third arg NOFORCE non-nil prevents next redisplay from
+moving point if displaying the window at POS makes point invisible;
+redisplay will then choose the WINDOW's start position by itself in
+that case, i.e. it will disregard POS if adhering to it will make
+point not visible in the window.
For reliable setting of WINDOW start position, make sure point is
at a position that will be visible when that start is in effect,
commit 24a6c7c8c01a607c4cb60f72f762cfa9de3adc48
Author: Eli Zaretskii
Date: Fri Apr 8 21:11:16 2022 +0300
Update and fix instructions and scripts for updating the Web pages
* admin/admin.el (manual-html-fix-index-2): Support Texinfo 6.8
and later by not converting TOC menus into tables. (Bug#49719)
* admin/upload-manuals (New directory): Invoke "cvs add" in
$webdir, to pick up the correct CVSROOT.
* admin/make-tarball.txt: Update the section about the Emacs Web
pages.
* etc/refcards/Makefile (pl-refcard.dvi): If mex.fmt cannot be
found, invoke 'mex' instead of 'tex'.
diff --git a/admin/admin.el b/admin/admin.el
index aa963be820..a6cb33017e 100644
--- a/admin/admin.el
+++ b/admin/admin.el
@@ -591,76 +591,81 @@ style=\"text-align:left\">")
(forward-line 1)
(setq done t)))))
(let (done open-td tag desc)
- ;; Convert the list that Makeinfo made into a table.
- (or (search-forward "
[ \t\n]*[ \t]*$")
+ (replace-match
+ (if open-td
+ " \n"
+ "") t t)
+ (setq done t))
+ (t
+ (if (eobp)
+ (error "Parse error in %s"
+ (file-name-nondirectory buffer-file-name)))
+ (unless open-td
+ (setq done t))))
+ (forward-line 1))))))
(defconst make-manuals-dist-output-variables
diff --git a/admin/make-tarball.txt b/admin/make-tarball.txt
index ec69302dae..17a4d9f807 100644
--- a/admin/make-tarball.txt
+++ b/admin/make-tarball.txt
@@ -315,17 +315,70 @@ looks like this:
-Regenerate the various manuals in manual/.
-The scripts admin/make-manuals and admin/upload-manuals summarize the process.
-
-If you have Texinfo installed locally, make-manuals might fail if it
-cannot find epsf.tex. In that case define in the environment
-
- TEXINPUTS=:/path/to/texinfo-tree/doc
-
-where /path/to/texinfo-tree is the absolute file name of the top-level
-directory where you have the Texinfo source tree. Then re-run
-make-manuals.
+Next, regenerate the various manuals in HTML, PDF, and PS formats:
+
+ Invoke ./admin/make-manuals from the top-level directory of the
+ Emacs source tree that contains the manuals for which you want to
+ produce HTML docs. This creates the 'manual' directory and
+ populates it with the necessary files.
+
+ If you have Texinfo installed locally, make-manuals might fail if it
+ cannot find epsf.tex. In that case define in the environment
+
+ TEXINPUTS=:/path/to/texinfo-tree/doc
+
+ where /path/to/texinfo-tree is the absolute file name of the
+ top-level directory where you have the Texinfo source tree. Then
+ re-run make-manuals.
+
+ make-manuals can also fail if the HTML manuals produced by Texinfo
+ violate some of the assumptions admin/admin.el makes about the
+ format of the produced HTML. Debug these problems and resolve them,
+ then re-run make-manuals. (Each time you run make-manuals, it
+ empties the manuals/ directory and regenerates the files there, but
+ if the files in manuals/ can be used without regeneration, i.e. if
+ the problem you solved doesn't affect the produced HTML, you can
+ invoke make-manuals with the -c switch, which will make the process
+ much faster.)
+
+Now change to the 'manual' directory and invoke upload-manuals:
+
+ ../admin/updload-manuals /path/to/webpages/cvs/checkout
+
+ where /path/to/webpages/cvs/checkout is the place where you have the
+ CVS checkout of the Emacs Web pages, with subdirectories 'manual'
+ and 'refcards'. This moves the produced manuals to directories in
+ the Web pages CVS checkout tree, and also invokes CVS commands to
+ commit changed files, add new files, and remove stale files that are
+ no longer part of the manuals.
+
+ If upload-manuals fails, resolve the problems and re-invoke it.
+ This requires running make-manuals again, since upload-manuals
+ destructively modifies the 'manual' directory where you invoke it.
+ Also, upload-manuals invokes "cvs commit -f", so if you run it
+ several times, some files will be committed more than once even
+ though they were not changed in-between. Suck it up.
+
+ All the added and removed files need to be committed, so next fire
+ up Emacs, type "C-x v d" to invoke vc-dir on the Web pages checkout,
+ and use "C-x v v" and other VC commands to commit all the files that
+ upload-manuals didn't automatically commit. (You can also do that
+ with manual CVS commands, of course, but this is not recommended.)
+
+ Next, make sure that manual/index.html file is consistent with the
+ info/dir file in the branch for which you are producing the manuals,
+ in that it mentions all the manuals. It could be outdated if
+ manuals were added or removed since the last release.
+
+ For each new manual, a file manual/MANUAL.html (where MANUAL is the
+ name of the manual) should be created from the template in
+ manual/eww.html, after editing the title and the Copyright years,
+ and the links in it changed to point to the appropriate files in the
+ manual/html_node/ and manual/html_mono/ subdirectories.
+
+ In addition, the file refcards/index.html should be audited to make
+ sure it includes the up-to-date list of refcards actually produced
+ and put under that subdirectory.
Browsing is one
way to check for any files that still need updating.
diff --git a/admin/upload-manuals b/admin/upload-manuals
index 1fa9865e65..1b7950ede8 100755
--- a/admin/upload-manuals
+++ b/admin/upload-manuals
@@ -334,7 +334,10 @@ for d in html_node/*; do
[ -e $webdir/manual/$d ] || {
echo "New directory: $d"
mkdir $webdir/manual/$d
- $cvs add $webdir/manual/$d || die "add error"
+ (
+ cd $webdir/manual
+ $cvs add $d || die "add error"
+ )
}
new=
diff --git a/etc/refcards/Makefile b/etc/refcards/Makefile
index 6f8913c5f0..4c5daa9f44 100644
--- a/etc/refcards/Makefile
+++ b/etc/refcards/Makefile
@@ -233,10 +233,11 @@ pl-refcard.pdf: $(pl_refcard_deps)
fi
$(ENVADD) pdftex -output-format=pdf pl-refcard.tex
pl-refcard.dvi: $(pl_refcard_deps)
- if ! kpsewhich -format=fmt mex > /dev/null; then \
- echo "No mex format found."; false; \
+ if kpsewhich -format=fmt mex > /dev/null; then \
+ $(ENVADD) tex pl-refcard.tex; \
+ else \
+ $(ENVADD) mex pl-refcard.tex; \
fi
- $(ENVADD) tex pl-refcard.tex
pl-refcard.ps: pl-refcard.dvi
dvips -t a4 -o $@ pl-refcard.dvi
commit 886339747b8d34fc09fd69a143cf548daf92dce6
Author: Michael Albinus
Date: Fri Apr 8 13:12:26 2022 +0200
Extend tramp-archive-test45-auto-load
* test/lisp/net/tramp-archive-tests.el (tramp-archive-test45-auto-load):
Extend test.
diff --git a/test/lisp/net/tramp-archive-tests.el b/test/lisp/net/tramp-archive-tests.el
index 5bdae2a760..aaa41d0c58 100644
--- a/test/lisp/net/tramp-archive-tests.el
+++ b/test/lisp/net/tramp-archive-tests.el
@@ -926,28 +926,31 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
(file-attributes %S \"/\")) \
(message \"tramp-archive loaded: %%s\" \
(featurep 'tramp-archive))))"))
- (dolist (default-directory
- `(,temporary-file-directory
- ;; Starting Emacs in a directory which has
- ;; `tramp-archive-file-name-regexp' syntax is
- ;; supported only with Emacs > 27.2 (sigh!).
- ;; (Bug#48476)
- ,(file-name-as-directory tramp-archive-test-directory)))
- (dolist (file `("/mock::foo" ,(concat tramp-archive-test-archive "foo")))
- (should
- (string-match
- (format
- "tramp-archive loaded: %s[[:ascii:]]+tramp-archive loaded: %s"
- (tramp-archive-file-name-p default-directory)
- (or (tramp-archive-file-name-p default-directory)
- (tramp-archive-file-name-p file)))
- (shell-command-to-string
- (format
- "%s -batch -Q -L %s --eval %s"
- (shell-quote-argument
- (expand-file-name invocation-name invocation-directory))
- (mapconcat #'shell-quote-argument load-path " -L ")
- (shell-quote-argument (format code file))))))))))
+ (dolist (enabled '(t nil))
+ (dolist (default-directory
+ `(,temporary-file-directory
+ ;; Starting Emacs in a directory which has
+ ;; `tramp-archive-file-name-regexp' syntax is
+ ;; supported only with Emacs > 27.2 (sigh!).
+ ;; (Bug#48476)
+ ,(file-name-as-directory tramp-archive-test-directory)))
+ (dolist (file `("/mock::foo" ,(concat tramp-archive-test-archive "foo")))
+ (should
+ (string-match
+ (format
+ "tramp-archive loaded: %s[[:ascii:]]+tramp-archive loaded: %s"
+ (tramp-archive-file-name-p default-directory)
+ (or (tramp-archive-file-name-p default-directory)
+ (and enabled (tramp-archive-file-name-p file))))
+ (shell-command-to-string
+ (format
+ "%s -batch -Q -L %s --eval %s --eval %s"
+ (shell-quote-argument
+ (expand-file-name invocation-name invocation-directory))
+ (mapconcat #'shell-quote-argument load-path " -L ")
+ (shell-quote-argument
+ (format "(setq tramp-archive-enabled %s)" enabled))
+ (shell-quote-argument (format code file)))))))))))
(ert-deftest tramp-archive-test45-delay-load ()
"Check that `tramp-archive' is loaded lazily, only when needed."
commit ff997ad7863c7c54a12d0cd07fa4c01766dfcce4
Author: Michael Albinus
Date: Fri Apr 8 13:12:03 2022 +0200
Ensure local `default-directory' in Tramp when needed
* lisp/net/tramp.el (tramp-process-running-p): Ensure local
`default-directory' when calling `list-system-processes' and
`process-attributes'.
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index a24d83f876..8baf72464d 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -5666,14 +5666,15 @@ verbosity of 6."
"Return t if system process PROCESS-NAME is running for `user-login-name'."
(when (stringp process-name)
(catch 'result
- (dolist (pid (list-system-processes))
- (when-let ((attributes (process-attributes pid))
- (comm (cdr (assoc 'comm attributes))))
- (and (string-equal (cdr (assoc 'user attributes)) (user-login-name))
- ;; The returned command name could be truncated to 15
- ;; characters. Therefore, we cannot check for `string-equal'.
- (string-prefix-p comm process-name)
- (throw 'result t)))))))
+ (let ((default-directory temporary-file-directory))
+ (dolist (pid (list-system-processes))
+ (when-let ((attributes (process-attributes pid))
+ (comm (cdr (assoc 'comm attributes))))
+ (and (string-equal (cdr (assoc 'user attributes)) (user-login-name))
+ ;; The returned command name could be truncated to 15
+ ;; characters. Therefore, we cannot check for `string-equal'.
+ (string-prefix-p comm process-name)
+ (throw 'result t))))))))
;; When calling "emacs -Q", `auth-source-search' won't be called. If
;; you want to debug exactly this case, call "emacs -Q --eval '(setq
commit 4f27588a16a8ce65db1aa5adfeca12bcbf44af3d
Author: Eli Zaretskii
Date: Fri Apr 8 09:48:15 2022 +0300
Clarify "idleness" in the ELisp manual
* doc/lispref/os.texi (Idle Timers): Clarify that waiting for
input with timeout doesn't make Emacs idle. Suggested by Ignacio
. (Bug#54371)
diff --git a/doc/lispref/os.texi b/doc/lispref/os.texi
index b1c19e384b..96cfff3f89 100644
--- a/doc/lispref/os.texi
+++ b/doc/lispref/os.texi
@@ -2284,7 +2284,8 @@ can use in calling @code{cancel-timer} (@pxref{Timers}).
@end deffn
@cindex idleness
- Emacs becomes @dfn{idle} when it starts waiting for user input, and
+ Emacs becomes @dfn{idle} when it starts waiting for user input
+(unless it waits for input with a timeout, @pxref{Reading One Event}), and
it remains idle until the user provides some input. If a timer is set
for five seconds of idleness, it runs approximately five seconds after
Emacs first becomes idle. Even if @var{repeat} is non-@code{nil},
commit 98abf01fd681931f8870569ff559b547579d7cef
Author: Jürgen Hötzel
Date: Fri Mar 4 10:08:14 2022 +0100
Use correct signal oldset in posix_spawn implementation
posix_spawn was restoring the wrong signal set, which still had
SIGCHLD and SIGINT masked, causing problems with child processes that
spawned child processes. (Bug#54667)
See the thread ending at
https://lists.gnu.org/archive/html/emacs-devel/2022-03/msg00067.html
for more details.
* src/callproc.c (emacs_spawn): Pass oldset parameter.
(emacs_posix_spawn_init_attributes): Use correct oldset.
(emacs_posix_spawn_init): Remove intermediate function.
(cherry picked from commit 8103b060d89ac63a12c439087bd46c30da72cd97)
diff --git a/src/callproc.c b/src/callproc.c
index 66a35d9f33..07eeadb3aa 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -1335,7 +1335,8 @@ emacs_posix_spawn_init_actions (posix_spawn_file_actions_t *actions,
}
static int
-emacs_posix_spawn_init_attributes (posix_spawnattr_t *attributes)
+emacs_posix_spawn_init_attributes (posix_spawnattr_t *attributes,
+ const sigset_t *oldset)
{
int error = posix_spawnattr_init (attributes);
if (error != 0)
@@ -1377,11 +1378,7 @@ emacs_posix_spawn_init_attributes (posix_spawnattr_t *attributes)
goto out;
/* Stop blocking SIGCHLD in the child. */
- sigset_t oldset;
- error = pthread_sigmask (SIG_SETMASK, NULL, &oldset);
- if (error != 0)
- goto out;
- error = posix_spawnattr_setsigmask (attributes, &oldset);
+ error = posix_spawnattr_setsigmask (attributes, oldset);
if (error != 0)
goto out;
@@ -1392,23 +1389,6 @@ emacs_posix_spawn_init_attributes (posix_spawnattr_t *attributes)
return error;
}
-static int
-emacs_posix_spawn_init (posix_spawn_file_actions_t *actions,
- posix_spawnattr_t *attributes, int std_in,
- int std_out, int std_err, const char *cwd)
-{
- int error = emacs_posix_spawn_init_actions (actions, std_in,
- std_out, std_err, cwd);
- if (error != 0)
- return error;
-
- error = emacs_posix_spawn_init_attributes (attributes);
- if (error != 0)
- return error;
-
- return 0;
-}
-
#endif
/* Start a new asynchronous subprocess. If successful, return zero
@@ -1443,9 +1423,12 @@ emacs_spawn (pid_t *newpid, int std_in, int std_out, int std_err,
if (use_posix_spawn)
{
/* Initialize optional attributes before blocking. */
- int error
- = emacs_posix_spawn_init (&actions, &attributes, std_in,
- std_out, std_err, cwd);
+ int error = emacs_posix_spawn_init_actions (&actions, std_in,
+ std_out, std_err, cwd);
+ if (error != 0)
+ return error;
+
+ error = emacs_posix_spawn_init_attributes (&attributes, oldset);
if (error != 0)
return error;
}
commit aab36e18950e23100718eaedb14ef9176f5d3da2
Author: Felix Dietrich
Date: Thu Apr 7 12:04:22 2022 +0200
Fix error in tramp-archive-autoload-file-name-handler
* lisp/net/tramp-archive.el (tramp-archive-autoload-file-name-handler):
Always call `tramp-autoload-file-name'. Otherwise, when
`tramp-archive-enabled’ is nil and
`tramp-archive-autoload-file-name-handler’ is in the
`file-name-handler-alist’ results in an error “Invalid handler in
`file-name-handler-alist” once Emacs calls
`tramp-archive-autoload-file-name-handler’ with a handler that
does not expect nil. Always returning nil is also false in
general.
Copyright-paperwork-exempt: yes
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el
index 22390ef45b..4b649edaab 100644
--- a/lisp/net/tramp-archive.el
+++ b/lisp/net/tramp-archive.el
@@ -356,14 +356,13 @@ arguments to pass to the OPERATION."
(progn (defun tramp-archive-autoload-file-name-handler (operation &rest args)
"Load Tramp archive file name handler, and perform OPERATION."
(defvar tramp-archive-autoload)
- (when tramp-archive-enabled
- ;; We cannot use `tramp-compat-temporary-file-directory' here due
- ;; to autoload. When installing Tramp's GNU ELPA package, there
- ;; might be an older, incompatible version active. We try to
- ;; overload this.
- (let ((default-directory temporary-file-directory)
- (tramp-archive-autoload t))
- (apply #'tramp-autoload-file-name-handler operation args)))))
+ (let (;; We cannot use `tramp-compat-temporary-file-directory' here
+ ;; due to autoload. When installing Tramp's GNU ELPA package,
+ ;; there might be an older, incompatible version active. We
+ ;; try to overload this.
+ (default-directory temporary-file-directory)
+ (tramp-archive-autoload tramp-archive-enabled))
+ (apply #'tramp-autoload-file-name-handler operation args))))
(put #'tramp-archive-autoload-file-name-handler 'tramp-autoload t)
commit 11a1f7817e293f67fb0b1136859c2f7393c1adfb
Merge: 71f51f1b9d 93974198b6
Author: Michael Albinus
Date: Thu Apr 7 11:57:40 2022 +0200
Merge branch 'emacs-28' of git.sv.gnu.org:/srv/git/emacs into emacs-28
commit 71f51f1b9dc8824f0cadc53b68dbc28629bce97f
Author: Michael Albinus
Date: Thu Apr 7 11:18:48 2022 +0200
Commit missing file from previous commit (Do not merge with master)
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index ee6e0e6c08..a24d83f876 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -185,7 +185,7 @@ See the variable `tramp-encoding-shell' for more information."
;; Since Emacs 26.1, `system-name' can return nil at build time if
;; Emacs is compiled with "--no-build-details". We do expect it to be
-;; a string. (Bug#44481)
+;; a string. (Bug#44481, Bug#54294)
(defconst tramp-system-name (or (system-name) "")
"The system name Tramp is running locally.")
@@ -1409,8 +1409,11 @@ calling HANDLER.")
;; internal data structure. Convenience functions for internal
;; data structure.
-;; The basic structure for remote file names. We use a list :type,
-;; in order to be compatible with Emacs 25.
+;; The basic structure for remote file names. We use a list :type, in
+;; order to be compatible with Emacs 25. We must autoload it in
+;; tramp-loaddefs.el, because some functions, which need it, wouldn't
+;; work otherwise when unloading / reloading Tramp. (Bug#50869)
+;;;###tramp-autoload
(cl-defstruct (tramp-file-name (:type list) :named)
method user domain host port localname hop)
@@ -2186,10 +2189,14 @@ the resulting error message."
(defun tramp-test-message (fmt-string &rest arguments)
"Emit a Tramp message according `default-directory'."
- (if (tramp-tramp-file-p default-directory)
- (apply #'tramp-message
- (tramp-dissect-file-name default-directory) 0 fmt-string arguments)
- (apply #'message fmt-string arguments)))
+ (cond
+ ((tramp-tramp-file-p default-directory)
+ (apply #'tramp-message
+ (tramp-dissect-file-name default-directory) 0 fmt-string arguments))
+ ((tramp-file-name-p (car tramp-current-connection))
+ (apply #'tramp-message
+ (car tramp-current-connection) 0 fmt-string arguments))
+ (t (apply #'message fmt-string arguments))))
(put #'tramp-test-message 'tramp-suppress-trace t)
@@ -2676,17 +2683,21 @@ Falls back to normal file name handler if no Tramp file name handler exists."
(load "tramp" 'noerror 'nomessage)))
(apply operation args)))
+(put #'tramp-autoload-file-name-handler 'tramp-autoload t)
+
;; `tramp-autoload-file-name-handler' must be registered before
;; evaluation of site-start and init files, because there might exist
;; remote files already, f.e. files kept via recentf-mode.
;;;###autoload
(progn (defun tramp-register-autoload-file-name-handlers ()
"Add Tramp file name handlers to `file-name-handler-alist' during autoload."
- (add-to-list 'file-name-handler-alist
- (cons tramp-autoload-file-name-regexp
- #'tramp-autoload-file-name-handler))
- (put #'tramp-autoload-file-name-handler 'safe-magic t)))
+ (unless (rassq #'tramp-file-name-handler file-name-handler-alist)
+ (add-to-list 'file-name-handler-alist
+ (cons tramp-autoload-file-name-regexp
+ #'tramp-autoload-file-name-handler))
+ (put #'tramp-autoload-file-name-handler 'safe-magic t))))
+(put #'tramp-register-autoload-file-name-handlers 'tramp-autoload t)
;;;###autoload (tramp-register-autoload-file-name-handlers)
(defun tramp-use-absolute-autoload-file-names ()
@@ -2799,6 +2810,7 @@ Add operations defined in `HANDLER-alist' to `tramp-file-name-handler'."
(string-prefix-p "tramp-" (symbol-name (cdr fnh))))
(setq file-name-handler-alist (delq fnh file-name-handler-alist))))))
+(put #'tramp-unload-file-name-handlers 'tramp-autoload t)
(add-hook 'tramp-unload-hook #'tramp-unload-file-name-handlers)
;;; File name handler functions for completion mode:
@@ -3378,6 +3390,10 @@ User is always nil."
(if (file-directory-p dir) dir (file-name-directory dir)) nil
(tramp-flush-directory-properties v localname)))
+(defvar tramp-tolerate-tilde nil
+ "Indicator, that not expandable tilde shall be tolerated.
+Let-bind it when necessary.")
+
(defun tramp-handle-expand-file-name (name &optional dir)
"Like `expand-file-name' for Tramp files."
;; If DIR is not given, use DEFAULT-DIRECTORY or "/".
@@ -3394,6 +3410,10 @@ User is always nil."
(with-parsed-tramp-file-name name nil
(unless (tramp-run-real-handler #'file-name-absolute-p (list localname))
(setq localname (concat "/" localname)))
+ ;; Tilde expansion is not possible.
+ (when (and (not tramp-tolerate-tilde)
+ (string-match-p "\\`\\(~[^/]*\\)\\(.*\\)\\'" localname))
+ (tramp-error v 'file-error "Cannot expand tilde in file `%s'" name))
;; Do not keep "/..".
(when (string-match-p "^/\\.\\.?$" localname)
(setq localname "/"))
@@ -3403,7 +3423,9 @@ User is always nil."
(let ((default-directory tramp-compat-temporary-file-directory))
(tramp-make-tramp-file-name
v (tramp-drop-volume-letter
- (tramp-run-real-handler #'expand-file-name (list localname))))))))
+ (if (string-match-p "\\`\\(~[^/]*\\)\\(.*\\)\\'" localname)
+ localname
+ (tramp-run-real-handler #'expand-file-name (list localname)))))))))
(defun tramp-handle-file-accessible-directory-p (filename)
"Like `file-accessible-directory-p' for Tramp files."
@@ -3890,16 +3912,19 @@ Return nil when there is no lockfile."
(insert-file-contents-literally lockname)
(buffer-string))))))
+(defvar tramp-lock-pid nil
+ "A random nunber local for every connection.
+Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'.")
+
(defun tramp-get-lock-pid (file)
"Determine pid for lockfile of FILE."
- ;; Some Tramp methods do not offer a connection process, but just a
- ;; network process as a place holder. Those processes use the
- ;; "lock-pid" connection property as fake pid, in fact it is the
- ;; time stamp the process is created.
- (let ((p (tramp-get-process (tramp-dissect-file-name file))))
- (number-to-string
- (or (process-id p)
- (tramp-get-connection-property p "lock-pid" (emacs-pid))))))
+ ;; Not all Tramp methods use an own process. So we use a random
+ ;; number, which is as good as a process id.
+ (with-current-buffer
+ (tramp-get-connection-buffer (tramp-dissect-file-name file))
+ (or tramp-lock-pid
+ (setq-local
+ tramp-lock-pid (number-to-string (random most-positive-fixnum))))))
(defconst tramp-lock-file-info-regexp
;; USER@HOST.PID[:BOOT_TIME]
@@ -3910,9 +3935,11 @@ Return nil when there is no lockfile."
"Like `file-locked-p' for Tramp files."
(when-let ((info (tramp-get-lock-file file))
(match (string-match tramp-lock-file-info-regexp info)))
- (or (and (string-equal (match-string 1 info) (user-login-name))
- (string-equal (match-string 2 info) (system-name))
+ (or ; Locked by me.
+ (and (string-equal (match-string 1 info) (user-login-name))
+ (string-equal (match-string 2 info) tramp-system-name)
(string-equal (match-string 3 info) (tramp-get-lock-pid file)))
+ ; User name.
(match-string 1 info))))
(defun tramp-handle-lock-file (file)
@@ -3921,6 +3948,14 @@ Return nil when there is no lockfile."
;; was visited.
(catch 'dont-lock
(unless (eq (file-locked-p file) t) ;; Locked by me.
+ (when (and buffer-file-truename
+ (not (verify-visited-file-modtime))
+ (file-exists-p file))
+ ;; In filelock.c, `userlock--ask-user-about-supersession-threat'
+ ;; is called, which also checks file contents. This is unwise
+ ;; for remote files.
+ (ask-user-about-supersession-threat file))
+
(when-let ((info (tramp-get-lock-file file))
(match (string-match tramp-lock-file-info-regexp info)))
(unless (ask-user-about-lock
@@ -3933,7 +3968,7 @@ Return nil when there is no lockfile."
;; USER@HOST.PID[:BOOT_TIME]
(info
(format
- "%s@%s.%s" (user-login-name) (system-name)
+ "%s@%s.%s" (user-login-name) tramp-system-name
(tramp-get-lock-pid file))))
;; Protect against security hole.
@@ -4198,7 +4233,9 @@ substitution. SPEC-LIST is a list of char/value pairs used for
(command (mapconcat #'tramp-shell-quote-argument command " "))
;; Set cwd and environment variables.
(command
- (append `("cd" ,localname "&&" "(" "env") env `(,command ")"))))
+ (append
+ `("cd" ,(tramp-shell-quote-argument localname) "&&" "(" "env")
+ env `(,command ")"))))
;; Check for `tramp-sh-file-name-handler', because something
;; is different between tramp-sh.el, and tramp-adb.el or
@@ -4464,10 +4501,7 @@ BUFFER might be a list, in this case STDERR is separated."
;; We must disable cygwin-mount file name
;; handlers and alike.
(tramp-run-real-handler
- #'substitute-in-file-name (list localname))))))))
- ;; "/m:h:~" does not work for completion. We use "/m:h:~/".
- (if (and (stringp localname) (string-equal "~" localname))
- (concat filename "/")
+ #'substitute-in-file-name (list localname)))))))
filename))))
(defconst tramp-time-dont-know '(0 0 0 1000)
@@ -4871,8 +4905,9 @@ performed successfully. Any other value means an error."
(tramp-message vec 6 "\n%s" (buffer-string)))
(if (eq exit 'ok)
(ignore-errors
- (and (functionp tramp-password-save-function)
- (funcall tramp-password-save-function)))
+ (when (functionp tramp-password-save-function)
+ (funcall tramp-password-save-function)
+ (setq tramp-password-save-function nil)))
;; Not successful.
(tramp-clear-passwd vec)
(delete-process proc)
@@ -5310,7 +5345,8 @@ be granted."
(offset (cond
((eq ?r access) 1)
((eq ?w access) 2)
- ((eq ?x access) 3))))
+ ((eq ?x access) 3)
+ ((eq ?s access) 3))))
(dolist (suffix '("string" "integer") result)
(setq
result
@@ -5343,7 +5379,8 @@ be granted."
(and
(eq access
(aref (tramp-compat-file-attribute-modes file-attr) offset))
- (or (equal remote-uid
+ (or (equal remote-uid unknown-id)
+ (equal remote-uid
(tramp-compat-file-attribute-user-id file-attr))
(equal unknown-id
(tramp-compat-file-attribute-user-id file-attr))))
@@ -5352,7 +5389,8 @@ be granted."
(eq access
(aref (tramp-compat-file-attribute-modes file-attr)
(+ offset 3)))
- (or (equal remote-gid
+ (or (equal remote-gid unknown-id)
+ (equal remote-gid
(tramp-compat-file-attribute-group-id file-attr))
(equal unknown-id
(tramp-compat-file-attribute-group-id
@@ -5660,7 +5698,9 @@ Invokes `password-read' if available, `read-passwd' else."
(or prompt
(with-current-buffer (process-buffer proc)
(tramp-check-for-regexp proc tramp-password-prompt-regexp)
- (format "%s for %s " (capitalize (match-string 1)) key))))
+ (if (string-match-p "passphrase" (match-string 1))
+ (match-string 0)
+ (format "%s for %s " (capitalize (match-string 1)) key)))))
(auth-source-creation-prompts `((secret . ,pw-prompt)))
;; Use connection-local value.
(auth-sources (with-current-buffer (process-buffer proc) auth-sources))
@@ -5872,6 +5912,8 @@ BODY is the backend specific code."
;; Maybe it's not loaded yet.
(ignore-errors (unload-feature 'tramp 'force))))
+(put #'tramp-unload-tramp 'tramp-autoload t)
+
(provide 'tramp)
(run-hooks 'tramp--startup-hook)
commit 93974198b62bea0350be503c8fc017e9d1a4542f
Author: Michael Albinus
Date: Thu Apr 7 11:18:48 2022 +0200
Commit missing file from previous commit
diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el
index ee6e0e6c08..a24d83f876 100644
--- a/lisp/net/tramp.el
+++ b/lisp/net/tramp.el
@@ -185,7 +185,7 @@ See the variable `tramp-encoding-shell' for more information."
;; Since Emacs 26.1, `system-name' can return nil at build time if
;; Emacs is compiled with "--no-build-details". We do expect it to be
-;; a string. (Bug#44481)
+;; a string. (Bug#44481, Bug#54294)
(defconst tramp-system-name (or (system-name) "")
"The system name Tramp is running locally.")
@@ -1409,8 +1409,11 @@ calling HANDLER.")
;; internal data structure. Convenience functions for internal
;; data structure.
-;; The basic structure for remote file names. We use a list :type,
-;; in order to be compatible with Emacs 25.
+;; The basic structure for remote file names. We use a list :type, in
+;; order to be compatible with Emacs 25. We must autoload it in
+;; tramp-loaddefs.el, because some functions, which need it, wouldn't
+;; work otherwise when unloading / reloading Tramp. (Bug#50869)
+;;;###tramp-autoload
(cl-defstruct (tramp-file-name (:type list) :named)
method user domain host port localname hop)
@@ -2186,10 +2189,14 @@ the resulting error message."
(defun tramp-test-message (fmt-string &rest arguments)
"Emit a Tramp message according `default-directory'."
- (if (tramp-tramp-file-p default-directory)
- (apply #'tramp-message
- (tramp-dissect-file-name default-directory) 0 fmt-string arguments)
- (apply #'message fmt-string arguments)))
+ (cond
+ ((tramp-tramp-file-p default-directory)
+ (apply #'tramp-message
+ (tramp-dissect-file-name default-directory) 0 fmt-string arguments))
+ ((tramp-file-name-p (car tramp-current-connection))
+ (apply #'tramp-message
+ (car tramp-current-connection) 0 fmt-string arguments))
+ (t (apply #'message fmt-string arguments))))
(put #'tramp-test-message 'tramp-suppress-trace t)
@@ -2676,17 +2683,21 @@ Falls back to normal file name handler if no Tramp file name handler exists."
(load "tramp" 'noerror 'nomessage)))
(apply operation args)))
+(put #'tramp-autoload-file-name-handler 'tramp-autoload t)
+
;; `tramp-autoload-file-name-handler' must be registered before
;; evaluation of site-start and init files, because there might exist
;; remote files already, f.e. files kept via recentf-mode.
;;;###autoload
(progn (defun tramp-register-autoload-file-name-handlers ()
"Add Tramp file name handlers to `file-name-handler-alist' during autoload."
- (add-to-list 'file-name-handler-alist
- (cons tramp-autoload-file-name-regexp
- #'tramp-autoload-file-name-handler))
- (put #'tramp-autoload-file-name-handler 'safe-magic t)))
+ (unless (rassq #'tramp-file-name-handler file-name-handler-alist)
+ (add-to-list 'file-name-handler-alist
+ (cons tramp-autoload-file-name-regexp
+ #'tramp-autoload-file-name-handler))
+ (put #'tramp-autoload-file-name-handler 'safe-magic t))))
+(put #'tramp-register-autoload-file-name-handlers 'tramp-autoload t)
;;;###autoload (tramp-register-autoload-file-name-handlers)
(defun tramp-use-absolute-autoload-file-names ()
@@ -2799,6 +2810,7 @@ Add operations defined in `HANDLER-alist' to `tramp-file-name-handler'."
(string-prefix-p "tramp-" (symbol-name (cdr fnh))))
(setq file-name-handler-alist (delq fnh file-name-handler-alist))))))
+(put #'tramp-unload-file-name-handlers 'tramp-autoload t)
(add-hook 'tramp-unload-hook #'tramp-unload-file-name-handlers)
;;; File name handler functions for completion mode:
@@ -3378,6 +3390,10 @@ User is always nil."
(if (file-directory-p dir) dir (file-name-directory dir)) nil
(tramp-flush-directory-properties v localname)))
+(defvar tramp-tolerate-tilde nil
+ "Indicator, that not expandable tilde shall be tolerated.
+Let-bind it when necessary.")
+
(defun tramp-handle-expand-file-name (name &optional dir)
"Like `expand-file-name' for Tramp files."
;; If DIR is not given, use DEFAULT-DIRECTORY or "/".
@@ -3394,6 +3410,10 @@ User is always nil."
(with-parsed-tramp-file-name name nil
(unless (tramp-run-real-handler #'file-name-absolute-p (list localname))
(setq localname (concat "/" localname)))
+ ;; Tilde expansion is not possible.
+ (when (and (not tramp-tolerate-tilde)
+ (string-match-p "\\`\\(~[^/]*\\)\\(.*\\)\\'" localname))
+ (tramp-error v 'file-error "Cannot expand tilde in file `%s'" name))
;; Do not keep "/..".
(when (string-match-p "^/\\.\\.?$" localname)
(setq localname "/"))
@@ -3403,7 +3423,9 @@ User is always nil."
(let ((default-directory tramp-compat-temporary-file-directory))
(tramp-make-tramp-file-name
v (tramp-drop-volume-letter
- (tramp-run-real-handler #'expand-file-name (list localname))))))))
+ (if (string-match-p "\\`\\(~[^/]*\\)\\(.*\\)\\'" localname)
+ localname
+ (tramp-run-real-handler #'expand-file-name (list localname)))))))))
(defun tramp-handle-file-accessible-directory-p (filename)
"Like `file-accessible-directory-p' for Tramp files."
@@ -3890,16 +3912,19 @@ Return nil when there is no lockfile."
(insert-file-contents-literally lockname)
(buffer-string))))))
+(defvar tramp-lock-pid nil
+ "A random nunber local for every connection.
+Do not set it manually, it is used buffer-local in `tramp-get-lock-pid'.")
+
(defun tramp-get-lock-pid (file)
"Determine pid for lockfile of FILE."
- ;; Some Tramp methods do not offer a connection process, but just a
- ;; network process as a place holder. Those processes use the
- ;; "lock-pid" connection property as fake pid, in fact it is the
- ;; time stamp the process is created.
- (let ((p (tramp-get-process (tramp-dissect-file-name file))))
- (number-to-string
- (or (process-id p)
- (tramp-get-connection-property p "lock-pid" (emacs-pid))))))
+ ;; Not all Tramp methods use an own process. So we use a random
+ ;; number, which is as good as a process id.
+ (with-current-buffer
+ (tramp-get-connection-buffer (tramp-dissect-file-name file))
+ (or tramp-lock-pid
+ (setq-local
+ tramp-lock-pid (number-to-string (random most-positive-fixnum))))))
(defconst tramp-lock-file-info-regexp
;; USER@HOST.PID[:BOOT_TIME]
@@ -3910,9 +3935,11 @@ Return nil when there is no lockfile."
"Like `file-locked-p' for Tramp files."
(when-let ((info (tramp-get-lock-file file))
(match (string-match tramp-lock-file-info-regexp info)))
- (or (and (string-equal (match-string 1 info) (user-login-name))
- (string-equal (match-string 2 info) (system-name))
+ (or ; Locked by me.
+ (and (string-equal (match-string 1 info) (user-login-name))
+ (string-equal (match-string 2 info) tramp-system-name)
(string-equal (match-string 3 info) (tramp-get-lock-pid file)))
+ ; User name.
(match-string 1 info))))
(defun tramp-handle-lock-file (file)
@@ -3921,6 +3948,14 @@ Return nil when there is no lockfile."
;; was visited.
(catch 'dont-lock
(unless (eq (file-locked-p file) t) ;; Locked by me.
+ (when (and buffer-file-truename
+ (not (verify-visited-file-modtime))
+ (file-exists-p file))
+ ;; In filelock.c, `userlock--ask-user-about-supersession-threat'
+ ;; is called, which also checks file contents. This is unwise
+ ;; for remote files.
+ (ask-user-about-supersession-threat file))
+
(when-let ((info (tramp-get-lock-file file))
(match (string-match tramp-lock-file-info-regexp info)))
(unless (ask-user-about-lock
@@ -3933,7 +3968,7 @@ Return nil when there is no lockfile."
;; USER@HOST.PID[:BOOT_TIME]
(info
(format
- "%s@%s.%s" (user-login-name) (system-name)
+ "%s@%s.%s" (user-login-name) tramp-system-name
(tramp-get-lock-pid file))))
;; Protect against security hole.
@@ -4198,7 +4233,9 @@ substitution. SPEC-LIST is a list of char/value pairs used for
(command (mapconcat #'tramp-shell-quote-argument command " "))
;; Set cwd and environment variables.
(command
- (append `("cd" ,localname "&&" "(" "env") env `(,command ")"))))
+ (append
+ `("cd" ,(tramp-shell-quote-argument localname) "&&" "(" "env")
+ env `(,command ")"))))
;; Check for `tramp-sh-file-name-handler', because something
;; is different between tramp-sh.el, and tramp-adb.el or
@@ -4464,10 +4501,7 @@ BUFFER might be a list, in this case STDERR is separated."
;; We must disable cygwin-mount file name
;; handlers and alike.
(tramp-run-real-handler
- #'substitute-in-file-name (list localname))))))))
- ;; "/m:h:~" does not work for completion. We use "/m:h:~/".
- (if (and (stringp localname) (string-equal "~" localname))
- (concat filename "/")
+ #'substitute-in-file-name (list localname)))))))
filename))))
(defconst tramp-time-dont-know '(0 0 0 1000)
@@ -4871,8 +4905,9 @@ performed successfully. Any other value means an error."
(tramp-message vec 6 "\n%s" (buffer-string)))
(if (eq exit 'ok)
(ignore-errors
- (and (functionp tramp-password-save-function)
- (funcall tramp-password-save-function)))
+ (when (functionp tramp-password-save-function)
+ (funcall tramp-password-save-function)
+ (setq tramp-password-save-function nil)))
;; Not successful.
(tramp-clear-passwd vec)
(delete-process proc)
@@ -5310,7 +5345,8 @@ be granted."
(offset (cond
((eq ?r access) 1)
((eq ?w access) 2)
- ((eq ?x access) 3))))
+ ((eq ?x access) 3)
+ ((eq ?s access) 3))))
(dolist (suffix '("string" "integer") result)
(setq
result
@@ -5343,7 +5379,8 @@ be granted."
(and
(eq access
(aref (tramp-compat-file-attribute-modes file-attr) offset))
- (or (equal remote-uid
+ (or (equal remote-uid unknown-id)
+ (equal remote-uid
(tramp-compat-file-attribute-user-id file-attr))
(equal unknown-id
(tramp-compat-file-attribute-user-id file-attr))))
@@ -5352,7 +5389,8 @@ be granted."
(eq access
(aref (tramp-compat-file-attribute-modes file-attr)
(+ offset 3)))
- (or (equal remote-gid
+ (or (equal remote-gid unknown-id)
+ (equal remote-gid
(tramp-compat-file-attribute-group-id file-attr))
(equal unknown-id
(tramp-compat-file-attribute-group-id
@@ -5660,7 +5698,9 @@ Invokes `password-read' if available, `read-passwd' else."
(or prompt
(with-current-buffer (process-buffer proc)
(tramp-check-for-regexp proc tramp-password-prompt-regexp)
- (format "%s for %s " (capitalize (match-string 1)) key))))
+ (if (string-match-p "passphrase" (match-string 1))
+ (match-string 0)
+ (format "%s for %s " (capitalize (match-string 1)) key)))))
(auth-source-creation-prompts `((secret . ,pw-prompt)))
;; Use connection-local value.
(auth-sources (with-current-buffer (process-buffer proc) auth-sources))
@@ -5872,6 +5912,8 @@ BODY is the backend specific code."
;; Maybe it's not loaded yet.
(ignore-errors (unload-feature 'tramp 'force))))
+(put #'tramp-unload-tramp 'tramp-autoload t)
+
(provide 'tramp)
(run-hooks 'tramp--startup-hook)
commit 009e88e002333b4090b021d24390c9137e5a2555
Author: Michael Albinus
Date: Thu Apr 7 11:17:52 2022 +0200
Merge with Tramp 2.5.2.3 (Do not merge with master)
* doc/misc/tramp.texi (Archive file names): Explicitly say how to
open an archive with Tramp (Bug#25076).
* doc/misc/trampver.texi:
* lisp/net/trampver.el: Change version to "2.5.3-pre".
* lisp/net/tramp-adb.el (tramp-adb-handle-process-file)
* lisp/net/tramp-sh.el (tramp-sh-handle-process-file):
* lisp/net/tramp-smb.el (tramp-smb-handle-process-file):
* lisp/net/tramp-sshfs.el (tramp-sshfs-handle-process-file):
Improve implementation. (Bug#53854)
* lisp/net/tramp-adb.el (tramp-adb-tolerate-tilde):
* lisp/net/tramp-sshfs.el (tramp-sshfs-tolerate-tilde):
New defuns. Advice `shell-mode' with them.
* lisp/net/tramp.el (tramp-register-autoload-file-name-handlers):
* lisp/net/tramp-archive.el (tramp-register-archive-file-name-handler):
Check, whether the real file name handler is already registered.
rules. (Bug#54542)
* lisp/net/tramp.el (tramp-autoload-file-name-handler)
(tramp-register-autoload-file-name-handlers)
(tramp-unload-file-name-handlers, tramp-unload-tramp):
* lisp/net/tramp-archive.el (tramp-archive-autoload-file-name-regexp)
(tramp-archive-autoload-file-name-handler)
(tramp-register-archive-file-name-handler):
Add `tramp-autoload' property.
* lisp/net/tramp-crypt.el (tramp-crypt-file-name-handler-alist):
* lisp/net/tramp-rclone.el (tramp-rclone-file-name-handler-alist):
* lisp/net/tramp-sudoedit.el (tramp-sudoedit-file-name-handler-alist):
* lisp/net/tramp-sshfs.el (tramp-sshfs-file-name-handler-alist):
Use `tramp-handle-file-notify-add-watch',
`tramp-handle-file-notify-rm-watch' and
`tramp-handle-file-notify-valid-p'.
* lisp/net/tramp-crypt.el (tramp-crypt-file-name-handler-alist):
Use `tramp-handle-insert-file-contents'.
* lisp/net/tramp-gvfs.el (tramp-gvfs-maybe-open-connection):
* lisp/net/tramp-rclone.el (tramp-rclone-maybe-open-connection):
* lisp/net/lisp/net/tramp-sshfs.el (tramp-sshfs-maybe-open-connection):
* tramp-sudoedit.el (tramp-sudoedit-maybe-open-connection): Do not
set "lock-pid" connection-property.
(tramp-sudoedit-handle-delete-file): Use "rm -f".
* lisp/net/tramp-gvfs.el (tramp-gvfs-handle-file-executable-p):
* lisp/net/tramp-sh.el (tramp-sh-handle-file-executable-p):
Check also for setuid/setgid bit.
(tramp-gvfs-handle-expand-file-name):
Respect `tramp-tolerate-tilde'.
* lisp/net/tramp-sh.el (tramp-sh-handle-insert-directory):
* lisp/net/tramp-smb.el (tramp-smb-handle-insert-directory):
Do not modify disk space information when
`dired--insert-disk-space' is available. (Bug#54512)
* lisp/net/tramp-sh.el (tramp-maybe-open-connection): Extend suppression
(tramp-get-remote-dev-tty): New defun.
(tramp-sh-handle-make-process): Use it.
* lisp/net/tramp-sshfs.el (tramp-methods) :
Add "-t -t" to `tramp-login-args'.
Add "-o dir_cache=no" to `tramp-mount-args'. (Bug#54126)
Add "-o transform_symlinks" to `tramp-mount-args'.
(tramp-sshfs-file-name-handler-alist):
Use `tramp-sshfs-handle-file-writable-p'.
(tramp-sshfs-handle-file-writable-p): New defun. (Bug#54130)
(tramp-sshfs-handle-write-region): Set file modification time.
(Bug#54016)
(tramp-sshfs-file-name-handler-alist):
Use `tramp-sshfs-handle-set-file-times'.
(tramp-sshfs-handle-set-file-times): New defun.
* test/lisp/net/tramp-tests.el (tramp--test-expensive-test-p):
Rename from `tramp--test-expensive-test'. Make it a defun. Adapt
all callees.
(tramp-test07-file-exists-p, tramp-test14-delete-directory)
(tramp-test18-file-attributes, tramp-test20-file-modes)
(tramp-test28-process-file, tramp-test29-start-file-process)
(tramp-test30-make-process, tramp-test32-shell-command)
(tramp-test33-environment-variables, tramp--test-check-files)
(tramp--test-special-characters, tramp-test46-unload): Adapt tests.
(tramp-test39-detect-external-change): New test.
(tramp-test29-start-file-process)
(tramp--test--deftest-direct-async-process)
(tramp-test30-make-process, tramp-test31-interrupt-process)
(tramp-test34-explicit-shell-file-name)
(tramp-test44-asynchronous-requests):
Add :tramp-asynchronous-processes tag.
(tramp--test-asynchronous-processes-p): New defun.
(tramp--test-hpux-p, tramp--test-macos-p): Protect against errors.
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index 28da4b385c..a8079a0fa4 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -4008,8 +4008,10 @@ methods}. Internally, file archives are mounted via the
@acronym{GVFS} @option{archive} method.
A file archive is a regular file of kind @file{/path/to/dir/file.EXT}.
-The extension @samp{.EXT} identifies the type of the file archive. A
-file inside a file archive, called archive file name, has the name
+The extension @samp{.EXT} identifies the type of the file archive. To
+examine the contents of an archive with Dired, open file name as if it
+were a directory (i.e., open @file{/path/to/dir/file.EXT/}). A file
+inside a file archive, called archive file name, has the name
@file{/path/to/dir/file.EXT/dir/file}.
Most of the @ref{Magic File Names, , magic file name operations,
diff --git a/doc/misc/trampver.texi b/doc/misc/trampver.texi
index ac44c27b0d..a6914a58d0 100644
--- a/doc/misc/trampver.texi
+++ b/doc/misc/trampver.texi
@@ -8,7 +8,7 @@
@c In the Tramp GIT, the version numbers are auto-frobbed from
@c tramp.el, and the bug report address is auto-frobbed from
@c configure.ac.
-@set trampver 2.5.2.28.1
+@set trampver 2.5.3-pre
@set trampurl https://www.gnu.org/software/tramp/
@set tramp-bug-report-address tramp-devel@@gnu.org
@set emacsver 25.1
diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el
index 3c1b032baf..aa0f558a2b 100644
--- a/lisp/net/tramp-adb.el
+++ b/lisp/net/tramp-adb.el
@@ -815,10 +815,10 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
;; Determine input.
(if (null infile)
(setq input (tramp-get-remote-null-device v))
- (setq infile (expand-file-name infile))
+ (setq infile (tramp-compat-file-name-unquote (expand-file-name infile)))
(if (tramp-equal-remote default-directory infile)
;; INFILE is on the same remote host.
- (setq input (tramp-file-local-name infile))
+ (setq input (tramp-unquote-file-local-name infile))
;; INFILE must be copied to remote host.
(setq input (tramp-make-tramp-temp-file v)
tmpinput (tramp-make-tramp-file-name v input))
@@ -849,7 +849,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(setcar (cdr destination) (expand-file-name (cadr destination)))
(if (tramp-equal-remote default-directory (cadr destination))
;; stderr is on the same remote host.
- (setq stderr (tramp-file-local-name (cadr destination)))
+ (setq stderr (tramp-unquote-file-local-name (cadr destination)))
;; stderr must be copied to remote host. The temporary
;; file must be deleted after execution.
(setq stderr (tramp-make-tramp-temp-file v)
@@ -870,7 +870,8 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
(setq ret (tramp-adb-send-command-and-check
v (format
"(cd %s; %s)"
- (tramp-shell-quote-argument localname) command)
+ (tramp-unquote-shell-quote-argument localname)
+ command)
t))
(unless (natnump ret) (setq ret 1))
;; We should add the output anyway.
@@ -900,8 +901,7 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored."
;; Cleanup. We remove all file cache values for the connection,
;; because the remote process could have changed them.
(when tmpinput (delete-file tmpinput))
-
- (unless process-file-side-effects
+ (when process-file-side-effects
(tramp-flush-directory-properties v ""))
;; Return exit status.
@@ -986,6 +986,10 @@ implementation will be used."
(name1 name)
(i 0))
+ (when (string-match-p "[[:multibyte:]]" command)
+ (tramp-error
+ v 'file-error "Cannot apply multi-byte command `%s'" command))
+
(while (get-process name1)
;; NAME must be unique as process name.
(setq i (1+ i)
@@ -1264,7 +1268,7 @@ connection if a previous connection has died for some reason."
(if (zerop (length device))
(tramp-error vec 'file-error "Device %s not connected" host))
(with-tramp-progress-reporter vec 3 "Opening adb shell connection"
- (let* ((coding-system-for-read 'utf-8-dos) ;is this correct?
+ (let* ((coding-system-for-read 'utf-8-dos) ; Is this correct?
(process-connection-type tramp-process-connection-type)
(args (if (> (length host) 0)
(list "-s" device "shell")
@@ -1368,6 +1372,24 @@ connection if a previous connection has died for some reason."
`(:application tramp :protocol ,tramp-adb-method)
'tramp-adb-connection-local-default-shell-profile))
+;; `shell-mode' tries to open remote files like "/adb::~/.history".
+;; This fails, because the tilde cannot be expanded. Tell
+;; `tramp-handle-expand-file-name' to tolerate this.
+(defun tramp-adb-tolerate-tilde (orig-fun)
+ "Advice for `shell-mode' to tolerate tilde in remote file names."
+ (let ((tramp-tolerate-tilde
+ (or tramp-tolerate-tilde
+ (equal (file-remote-p default-directory 'method)
+ tramp-adb-method))))
+ (funcall orig-fun)))
+
+(add-function
+ :around (symbol-function #'shell-mode) #'tramp-adb-tolerate-tilde)
+(add-hook 'tramp-adb-unload-hook
+ (lambda ()
+ (remove-function
+ (symbol-function #'shell-mode) #'tramp-adb-tolerate-tilde)))
+
(add-hook 'tramp-unload-hook
(lambda ()
(unload-feature 'tramp-adb 'force)))
diff --git a/lisp/net/tramp-archive.el b/lisp/net/tramp-archive.el
index 1b5f42a991..22390ef45b 100644
--- a/lisp/net/tramp-archive.el
+++ b/lisp/net/tramp-archive.el
@@ -188,6 +188,8 @@ It must be supported by libarchive(3).")
"\\)" ;; \1
"\\(" "/" ".*" "\\)" "\\'"))) ;; \2
+(put #'tramp-archive-autoload-file-name-regexp 'tramp-autoload t)
+
;; In older Emacsen (prior 27.1), `tramp-archive-autoload-file-name-regexp'
;; is not autoloaded. So we cannot expect it to be known in
;; tramp-loaddefs.el. But it exists, when tramp-archive.el is loaded.
@@ -363,15 +365,21 @@ arguments to pass to the OPERATION."
(tramp-archive-autoload t))
(apply #'tramp-autoload-file-name-handler operation args)))))
+(put #'tramp-archive-autoload-file-name-handler 'tramp-autoload t)
+
;;;###autoload
(progn (defun tramp-register-archive-file-name-handler ()
"Add archive file name handler to `file-name-handler-alist'."
- (when tramp-archive-enabled
+ (when (and tramp-archive-enabled
+ (not
+ (rassq #'tramp-archive-file-name-handler file-name-handler-alist)))
(add-to-list 'file-name-handler-alist
(cons (tramp-archive-autoload-file-name-regexp)
#'tramp-archive-autoload-file-name-handler))
(put #'tramp-archive-autoload-file-name-handler 'safe-magic t))))
+(put #'tramp-register-archive-file-name-handler 'tramp-autoload t)
+
;;;###autoload
(progn
(add-hook 'after-init-hook #'tramp-register-archive-file-name-handler)
diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el
index d35f7ffa4e..347da916ed 100644
--- a/lisp/net/tramp-cache.el
+++ b/lisp/net/tramp-cache.el
@@ -49,8 +49,6 @@
;; an open connection. Examples: "scripts" keeps shell script
;; definitions already sent to the remote shell, "last-cmd-time" is
;; the time stamp a command has been sent to the remote process.
-;; "lock-pid" is the timestamp a (network) process is created, it is
-;; used instead of the pid in file locks.
;;
;; - The key is nil. These are temporary properties related to the
;; local machine. Examples: "parse-passwd" and "parse-group" keep
diff --git a/lisp/net/tramp-crypt.el b/lisp/net/tramp-crypt.el
index e8313463da..5028e48932 100644
--- a/lisp/net/tramp-crypt.el
+++ b/lisp/net/tramp-crypt.el
@@ -192,9 +192,9 @@ If NAME doesn't belong to a crypted remote directory, retun nil."
;; `file-name-nondirectory' performed by default handler.
;; `file-name-sans-versions' performed by default handler.
(file-newer-than-file-p . tramp-handle-file-newer-than-file-p)
- (file-notify-add-watch . ignore)
- (file-notify-rm-watch . ignore)
- (file-notify-valid-p . ignore)
+ (file-notify-add-watch . tramp-handle-file-notify-add-watch)
+ (file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
+ (file-notify-valid-p . tramp-handle-file-notify-valid-p)
(file-ownership-preserved-p . tramp-crypt-handle-file-ownership-preserved-p)
(file-readable-p . tramp-crypt-handle-file-readable-p)
(file-regular-p . tramp-handle-file-regular-p)
@@ -207,7 +207,7 @@ If NAME doesn't belong to a crypted remote directory, retun nil."
(find-backup-file-name . tramp-handle-find-backup-file-name)
;; `get-file-buffer' performed by default handler.
(insert-directory . tramp-crypt-handle-insert-directory)
- ;; `insert-file-contents' performed by default handler.
+ (insert-file-contents . tramp-handle-insert-file-contents)
(load . tramp-handle-load)
(lock-file . tramp-crypt-handle-lock-file)
(make-auto-save-file-name . tramp-handle-make-auto-save-file-name)
diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el
index 0bba894cdb..c09c016e64 100644
--- a/lisp/net/tramp-gvfs.el
+++ b/lisp/net/tramp-gvfs.el
@@ -1160,10 +1160,9 @@ file names."
(tramp-get-connection-property v "default-location" "~")
nil t localname 1)))
;; Tilde expansion is not possible.
- (when (string-match-p "\\`\\(~[^/]*\\)\\(.*\\)\\'" localname)
- (tramp-error
- v 'file-error
- "Cannot expand tilde in file `%s'" name))
+ (when (and (not tramp-tolerate-tilde)
+ (string-match-p "\\`\\(~[^/]*\\)\\(.*\\)\\'" localname))
+ (tramp-error v 'file-error "Cannot expand tilde in file `%s'" name))
(unless (tramp-run-real-handler #'file-name-absolute-p (list localname))
(setq localname (concat "/" localname)))
;; We do not pass "/..".
@@ -1181,7 +1180,9 @@ file names."
;; No tilde characters in file name, do normal
;; `expand-file-name' (this does "/./" and "/../").
(tramp-make-tramp-file-name
- v (tramp-run-real-handler #'expand-file-name (list localname))))))
+ v (if (string-match-p "\\`\\(~[^/]*\\)\\(.*\\)\\'" localname)
+ localname
+ (tramp-run-real-handler #'expand-file-name (list localname)))))))
(defun tramp-gvfs-get-directory-attributes (directory)
"Return GVFS attributes association list of all files in DIRECTORY."
@@ -1396,7 +1397,8 @@ If FILE-SYSTEM is non-nil, return file system attributes."
"Like `file-executable-p' for Tramp files."
(with-parsed-tramp-file-name filename nil
(with-tramp-file-property v localname "file-executable-p"
- (tramp-check-cached-permissions v ?x))))
+ (or (tramp-check-cached-permissions v ?x)
+ (tramp-check-cached-permissions v ?s)))))
(defun tramp-gvfs-handle-file-name-all-completions (filename directory)
"Like `file-name-all-completions' for Tramp files."
@@ -1612,22 +1614,18 @@ ID-FORMAT valid values are `string' and `integer'."
(tramp-file-name-user vec)
(when-let ((localname
(tramp-get-connection-property
- (tramp-get-process vec) "share"
- (tramp-get-connection-property vec "default-location" nil))))
+ (tramp-get-process vec) "share" nil)))
(tramp-compat-file-attribute-user-id
- (file-attributes
- (tramp-make-tramp-file-name vec localname) id-format)))))
+ (file-attributes (tramp-make-tramp-file-name vec localname) id-format)))))
(defun tramp-gvfs-handle-get-remote-gid (vec id-format)
"The gid of the remote connection VEC, in ID-FORMAT.
ID-FORMAT valid values are `string' and `integer'."
(when-let ((localname
(tramp-get-connection-property
- (tramp-get-process vec) "share"
- (tramp-get-connection-property vec "default-location" nil))))
+ (tramp-get-process vec) "share" nil)))
(tramp-compat-file-attribute-group-id
- (file-attributes
- (tramp-make-tramp-file-name vec localname) id-format))))
+ (file-attributes (tramp-make-tramp-file-name vec localname) id-format))))
(defun tramp-gvfs-handle-set-file-uid-gid (filename &optional uid gid)
"Like `tramp-set-file-uid-gid' for Tramp files."
@@ -2134,9 +2132,6 @@ connection if a previous connection has died for some reason."
(process-put p 'vector vec)
(set-process-query-on-exit-flag p nil)
- ;; Mark process for filelock.
- (tramp-set-connection-property p "lock-pid" (truncate (time-to-seconds)))
-
;; Set connection-local variables.
(tramp-set-connection-local-variables vec)))
@@ -2256,13 +2251,7 @@ connection if a previous connection has died for some reason."
COMMAND is a command from the gvfs-* utilities. It is replaced
by the corresponding gio tool call if available. `call-process'
is applied, and it returns t if the return code is zero."
- (let* ((locale (tramp-get-local-locale vec))
- (process-environment
- (append
- `(,(format "LANG=%s" locale)
- ,(format "LANGUAGE=%s" locale)
- ,(format "LC_ALL=%s" locale))
- process-environment)))
+ (let ((locale (tramp-get-local-locale vec)))
(when (tramp-gvfs-gio-tool-p vec)
;; Use gio tool.
(setq args (cons (cdr (assoc command tramp-gvfs-gio-mapping))
@@ -2272,7 +2261,14 @@ is applied, and it returns t if the return code is zero."
(with-current-buffer (tramp-get-connection-buffer vec)
(tramp-gvfs-maybe-open-connection vec)
(erase-buffer)
- (or (zerop (apply #'tramp-call-process vec command nil t nil args))
+ (or (zerop
+ (apply
+ #'tramp-call-process vec "env" nil t nil
+ (append `(,(format "LANG=%s" locale)
+ ,(format "LANGUAGE=%s" locale)
+ ,(format "LC_ALL=%s" locale)
+ ,command)
+ args)))
;; Remove information about mounted connection.
(and (tramp-flush-file-properties vec "/") nil)))))
diff --git a/lisp/net/tramp-rclone.el b/lisp/net/tramp-rclone.el
index 20e983c77d..318df2de61 100644
--- a/lisp/net/tramp-rclone.el
+++ b/lisp/net/tramp-rclone.el
@@ -106,9 +106,9 @@
(file-name-nondirectory . tramp-handle-file-name-nondirectory)
;; `file-name-sans-versions' performed by default handler.
(file-newer-than-file-p . tramp-handle-file-newer-than-file-p)
- (file-notify-add-watch . ignore)
- (file-notify-rm-watch . ignore)
- (file-notify-valid-p . ignore)
+ (file-notify-add-watch . tramp-handle-file-notify-add-watch)
+ (file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
+ (file-notify-valid-p . tramp-handle-file-notify-valid-p)
(file-ownership-preserved-p . ignore)
(file-readable-p . tramp-fuse-handle-file-readable-p)
(file-regular-p . tramp-handle-file-regular-p)
@@ -362,10 +362,6 @@ connection if a previous connection has died for some reason."
(process-put p 'vector vec)
(set-process-query-on-exit-flag p nil)
- ;; Mark process for filelock.
- (tramp-set-connection-property
- p "lock-pid" (truncate (time-to-seconds)))
-
;; Set connection-local variables.
(tramp-set-connection-local-variables vec)))
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index de4d579740..54fb539a56 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -1574,6 +1574,7 @@ ID-FORMAT valid values are `string' and `integer'."
;; Examine `file-attributes' cache to see if request can be
;; satisfied without remote operation.
(or (tramp-check-cached-permissions v ?x)
+ (tramp-check-cached-permissions v ?s)
(tramp-run-test "-x" filename)))))
(defun tramp-sh-handle-file-readable-p (filename)
@@ -2663,7 +2664,9 @@ The method used must be an out-of-band method."
;; Try to insert the amount of free space.
(goto-char (point-min))
;; First find the line to put it on.
- (when (re-search-forward "^\\([[:space:]]*total\\)" nil t)
+ (when (and (re-search-forward "^\\([[:space:]]*total\\)" nil t)
+ ;; Emacs 29.1 or later.
+ (not (fboundp 'dired--insert-disk-space)))
(when-let ((available (get-free-disk-space ".")))
;; Replace "total" with "total used", to avoid confusion.
(replace-match "\\1 used in directory")
@@ -2817,8 +2820,10 @@ implementation will be used."
(string-match-p "sh$" program)
(= (length args) 2)
(string-equal "-c" (car args))
- ;; Don't if there is a string.
- (not (string-match-p "'\\|\"" (cadr args)))))
+ ;; Don't if there is a quoted string.
+ (not (string-match-p "'\\|\"" (cadr args)))
+ ;; Check, that /dev/tty is usable.
+ (tramp-get-remote-dev-tty v)))
;; When PROGRAM is nil, we just provide a tty.
(args (if (not heredoc) args
(let ((i 250))
@@ -3080,10 +3085,10 @@ implementation will be used."
;; Determine input.
(if (null infile)
(setq input (tramp-get-remote-null-device v))
- (setq infile (expand-file-name infile))
+ (setq infile (tramp-compat-file-name-unquote (expand-file-name infile)))
(if (tramp-equal-remote default-directory infile)
;; INFILE is on the same remote host.
- (setq input (tramp-file-local-name infile))
+ (setq input (tramp-unquote-file-local-name infile))
;; INFILE must be copied to remote host.
(setq input (tramp-make-tramp-temp-file v)
tmpinput (tramp-make-tramp-file-name v input 'nohop))
@@ -3114,7 +3119,7 @@ implementation will be used."
(setcar (cdr destination) (expand-file-name (cadr destination)))
(if (tramp-equal-remote default-directory (cadr destination))
;; stderr is on the same remote host.
- (setq stderr (tramp-file-local-name (cadr destination)))
+ (setq stderr (tramp-unquote-file-local-name (cadr destination)))
;; stderr must be copied to remote host. The temporary
;; file must be deleted after execution.
(setq stderr (tramp-make-tramp-temp-file v)
@@ -3135,7 +3140,8 @@ implementation will be used."
(setq ret (tramp-send-command-and-check
v (format
"cd %s && %s"
- (tramp-shell-quote-argument localname) command)
+ (tramp-unquote-shell-quote-argument localname)
+ command)
t t t))
(unless (natnump ret) (setq ret 1))
;; We should add the output anyway.
@@ -3167,8 +3173,7 @@ implementation will be used."
;; Cleanup. We remove all file cache values for the connection,
;; because the remote process could have changed them.
(when tmpinput (delete-file tmpinput))
-
- (unless process-file-side-effects
+ (when process-file-side-effects
(tramp-flush-directory-properties v ""))
;; Return exit status.
@@ -4093,13 +4098,10 @@ file exists and nonzero exit status otherwise."
;; The algorithm is as follows: we try a list of several commands.
;; For each command, we first run `$cmd /' -- this should return
;; true, as the root directory always exists. And then we run
- ;; `$cmd /this\ file\ does\ not\ exist ', hoping that the file indeed
- ;; does not exist. This should return false. We use the first
- ;; command we find that seems to work.
+ ;; `$cmd /\ this\ file\ does\ not\ exist\ ', hoping that the file
+ ;; indeed does not exist. This should return false. We use the
+ ;; first command we find that seems to work.
;; The list of commands to try is as follows:
- ;; `ls -d' This works on most systems, but NetBSD 1.4
- ;; has a bug: `ls' always returns zero exit
- ;; status, even for files which don't exist.
;; `test -e' Some Bourne shells have a `test' builtin
;; which does not know the `-e' option.
;; `/bin/test -e' For those, the `test' binary on disk normally
@@ -4107,6 +4109,10 @@ file exists and nonzero exit status otherwise."
;; is sometimes `/bin/test' and sometimes it's
;; `/usr/bin/test'.
;; `/usr/bin/test -e' In case `/bin/test' does not exist.
+ ;; `ls -d' This works on most systems, but NetBSD 1.4
+ ;; has a bug: `ls' always returns zero exit
+ ;; status, even for files which don't exist.
+
(unless (or
(ignore-errors
(and (setq result (format "%s -e" (tramp-get-test-command vec)))
@@ -4839,6 +4845,7 @@ connection if a previous connection has died for some reason."
;; If Tramp opens the same connection within a short time frame,
;; there is a problem. We shall signal this.
(unless (or (process-live-p p)
+ (and (processp p) (not non-essential))
(not (tramp-file-name-equal-p
vec (car tramp-current-connection)))
(time-less-p
@@ -5815,6 +5822,12 @@ This command is returned only if `delete-by-moving-to-trash' is non-nil."
command))
(delete-file tmpfile)))))
+(defun tramp-get-remote-dev-tty (vec)
+ "Check, whether remote /dev/tty is usable."
+ (with-tramp-connection-property vec "dev-tty"
+ (tramp-send-command-and-check
+ vec "echo %s" command stderr)))
+
(unwind-protect
(apply
#'tramp-call-process
v (tramp-get-method-parameter v 'tramp-login-program)
- infile destination display
+ nil outbuf display
(tramp-expand-args
v 'tramp-login-args
?h (or (tramp-file-name-host v) "")
@@ -256,7 +316,20 @@ arguments to pass to the OPERATION."
?p (or (tramp-file-name-port v) "")
?l command))
- (unless process-file-side-effects
+ ;; Synchronize stderr.
+ (when tmpstderr
+ (tramp-cleanup-connection v 'keep-debug 'keep-password)
+ (tramp-fuse-unmount v))
+
+ ;; Provide error file.
+ (when tmpstderr
+ (rename-file tmpstderr (cadr destination) t))
+
+ ;; Cleanup. We remove all file cache values for the
+ ;; connection, because the remote process could have changed
+ ;; them.
+ (when tmpinput (delete-file tmpinput))
+ (when process-file-side-effects
(tramp-flush-directory-properties v ""))))))
(defun tramp-sshfs-handle-rename-file
@@ -285,6 +358,15 @@ arguments to pass to the OPERATION."
(tramp-compat-set-file-modes
(tramp-fuse-local-file-name filename) mode flag))))
+(defun tramp-sshfs-handle-set-file-times (filename &optional timestamp flag)
+ "Like `set-file-times' for Tramp files."
+ (or (file-exists-p filename) (write-region "" nil filename nil 0))
+ (with-parsed-tramp-file-name filename nil
+ (unless (and (eq flag 'nofollow) (file-symlink-p filename))
+ (tramp-flush-file-properties v localname)
+ (tramp-compat-set-file-times
+ (tramp-fuse-local-file-name filename) timestamp flag))))
+
(defun tramp-sshfs-handle-write-region
(start end filename &optional append visit lockname mustbenew)
"Like `write-region' for Tramp files."
@@ -313,6 +395,13 @@ arguments to pass to the OPERATION."
start end (tramp-fuse-local-file-name filename) append 'nomessage)
(tramp-flush-file-properties v localname))
+ ;; Set file modification time.
+ (when (or (eq visit t) (stringp visit))
+ (set-visited-file-modtime
+ (or (tramp-compat-file-attribute-modification-time
+ (file-attributes filename))
+ (current-time))))
+
;; Unlock file.
(when file-locked
;; `unlock-file' exists since Emacs 28.1.
@@ -345,9 +434,6 @@ connection if a previous connection has died for some reason."
(process-put p 'vector vec)
(set-process-query-on-exit-flag p nil)
- ;; Mark process for filelock.
- (tramp-set-connection-property p "lock-pid" (truncate (time-to-seconds)))
-
;; Set connection-local variables.
(tramp-set-connection-local-variables vec)))
@@ -386,6 +472,24 @@ connection if a previous connection has died for some reason."
(with-tramp-connection-property
vec "gid-string" (tramp-get-local-gid 'string)))
+;; `shell-mode' tries to open remote files like "/sshfs:user@host:~/.history".
+;; This fails, because the tilde cannot be expanded. Tell
+;; `tramp-handle-expand-file-name' to tolerate this.
+(defun tramp-sshfs-tolerate-tilde (orig-fun)
+ "Advice for `shell-mode' to tolerate tilde in remote file names."
+ (let ((tramp-tolerate-tilde
+ (or tramp-tolerate-tilde
+ (equal (file-remote-p default-directory 'method)
+ tramp-sshfs-method))))
+ (funcall orig-fun)))
+
+(add-function
+ :around (symbol-function #'shell-mode) #'tramp-sshfs-tolerate-tilde)
+(add-hook 'tramp-sshfs-unload-hook
+ (lambda ()
+ (remove-function
+ (symbol-function #'shell-mode) #'tramp-sshfs-tolerate-tilde)))
+
(add-hook 'tramp-unload-hook
(lambda ()
(unload-feature 'tramp-sshfs 'force)))
diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el
index c4222b28a2..06100fbde0 100644
--- a/lisp/net/tramp-sudoedit.el
+++ b/lisp/net/tramp-sudoedit.el
@@ -99,9 +99,9 @@ See `tramp-actions-before-shell' for more info.")
(file-name-nondirectory . tramp-handle-file-name-nondirectory)
;; `file-name-sans-versions' performed by default handler.
(file-newer-than-file-p . tramp-handle-file-newer-than-file-p)
- (file-notify-add-watch . ignore)
- (file-notify-rm-watch . ignore)
- (file-notify-valid-p . ignore)
+ (file-notify-add-watch . tramp-handle-file-notify-add-watch)
+ (file-notify-rm-watch . tramp-handle-file-notify-rm-watch)
+ (file-notify-valid-p . tramp-handle-file-notify-valid-p)
(file-ownership-preserved-p . ignore)
(file-readable-p . tramp-sudoedit-handle-file-readable-p)
(file-regular-p . tramp-handle-file-regular-p)
@@ -336,7 +336,7 @@ absolute file names."
(if (and delete-by-moving-to-trash trash)
(move-file-to-trash filename)
(unless (tramp-sudoedit-send-command
- v "rm" (tramp-compat-file-name-unquote localname))
+ v "rm" "-f" (tramp-compat-file-name-unquote localname))
;; Propagate the error.
(with-current-buffer (tramp-get-connection-buffer v)
(goto-char (point-min))
@@ -789,9 +789,6 @@ connection if a previous connection has died for some reason."
(process-put p 'vector vec)
(set-process-query-on-exit-flag p nil)
- ;; Mark process for filelock.
- (tramp-set-connection-property p "lock-pid" (truncate (time-to-seconds)))
-
;; Set connection-local variables.
(tramp-set-connection-local-variables vec)
diff --git a/lisp/net/trampver.el b/lisp/net/trampver.el
index 1f41a92676..9c04abc828 100644
--- a/lisp/net/trampver.el
+++ b/lisp/net/trampver.el
@@ -7,7 +7,7 @@
;; Maintainer: Michael Albinus
;; Keywords: comm, processes
;; Package: tramp
-;; Version: 2.5.2.28.1
+;; Version: 2.5.3-pre
;; Package-Requires: ((emacs "25.1"))
;; Package-Type: multi
;; URL: https://www.gnu.org/software/tramp/
@@ -40,7 +40,7 @@
;; ./configure" to change them.
;;;###tramp-autoload
-(defconst tramp-version "2.5.2.28.1"
+(defconst tramp-version "2.5.3-pre"
"This version of Tramp.")
;;;###tramp-autoload
@@ -76,7 +76,7 @@
;; Check for Emacs version.
(let ((x (if (not (string-lessp emacs-version "25.1"))
"ok"
- (format "Tramp 2.5.2.28.1 is not fit for %s"
+ (format "Tramp 2.5.3-pre is not fit for %s"
(replace-regexp-in-string "\n" "" (emacs-version))))))
(unless (string-equal "ok" x) (error "%s" x)))
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el
index 8e11e509b5..8b999a6e34 100644
--- a/test/lisp/net/tramp-tests.el
+++ b/test/lisp/net/tramp-tests.el
@@ -160,13 +160,6 @@ being the result.")
;; Return result.
(cdr tramp--test-enabled-checked))
-(defsubst tramp--test-expensive-test ()
- "Whether expensive tests are run."
- (ert-select-tests
- (ert--stats-selector ert--current-run-stats)
- (list (make-ert-test :name (ert-test-name (ert-running-test))
- :body nil :tags '(:expensive-test)))))
-
(defun tramp--test-make-temp-name (&optional local quoted)
"Return a temporary file name for test.
If LOCAL is non-nil, a local file name is returned.
@@ -2298,7 +2291,7 @@ This checks also `file-name-as-directory', `file-name-directory',
"Check `file-exist-p', `write-region' and `delete-file'."
(skip-unless (tramp--test-enabled))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let ((tmp-name (tramp--test-make-temp-name nil quoted)))
(should-not (file-exists-p tmp-name))
(write-region "foo" nil tmp-name)
@@ -2306,8 +2299,10 @@ This checks also `file-name-as-directory', `file-name-directory',
(delete-file tmp-name)
(should-not (file-exists-p tmp-name))
- ;; Trashing files doesn't work on MS Windows, and for crypted remote files.
- (unless (or (tramp--test-windows-nt-p) (tramp--test-crypt-p))
+ ;; Trashing files doesn't work when `system-move-file-to-trash'
+ ;; is defined (on MS Windows and macOS), and for crypted remote
+ ;; files.
+ (unless (or (fboundp 'system-move-file-to-trash) (tramp--test-crypt-p))
(let ((trash-directory (tramp--test-make-temp-name 'local quoted))
(delete-by-moving-to-trash t))
(make-directory trash-directory)
@@ -2331,7 +2326,7 @@ This checks also `file-name-as-directory', `file-name-directory',
"Check `file-local-copy'."
(skip-unless (tramp--test-enabled))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
tmp-name2)
(unwind-protect
@@ -2363,7 +2358,7 @@ This checks also `file-name-as-directory', `file-name-directory',
"Check `insert-file-contents'."
(skip-unless (tramp--test-enabled))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let ((tmp-name (tramp--test-make-temp-name nil quoted)))
(unwind-protect
(with-temp-buffer
@@ -2400,7 +2395,7 @@ This checks also `file-name-as-directory', `file-name-directory',
"Check `write-region'."
(skip-unless (tramp--test-enabled))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let ((tmp-name (tramp--test-make-temp-name nil quoted))
(inhibit-message t))
(unwind-protect
@@ -2541,8 +2536,9 @@ This checks also `file-name-as-directory', `file-name-directory',
(skip-unless (tramp--test-enabled))
;; `filename-non-special' has been fixed in Emacs 27.1, see Bug#29579.
- (dolist (quoted (if (and (tramp--test-expensive-test) (tramp--test-emacs27-p))
- '(nil t) '(nil)))
+ (dolist (quoted
+ (if (and (tramp--test-expensive-test-p) (tramp--test-emacs27-p))
+ '(nil t) '(nil)))
(let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (tramp--test-make-temp-name nil quoted))
(tmp-name3 (tramp--test-make-temp-name 'local quoted)))
@@ -2569,7 +2565,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(with-temp-buffer
(insert-file-contents target)
(should (string-equal (buffer-string) "foo")))
- (when (tramp--test-expensive-test)
+ (when (tramp--test-expensive-test-p)
(should-error
(copy-file source target)
:type 'file-already-exists))
@@ -2588,7 +2584,8 @@ This checks also `file-name-as-directory', `file-name-directory',
(make-directory target)
(should (file-directory-p target))
;; This has been changed in Emacs 26.1.
- (when (and (tramp--test-expensive-test) (tramp--test-emacs26-p))
+ (when (and (tramp--test-expensive-test-p)
+ (tramp--test-emacs26-p))
(should-error
(copy-file source target)
:type 'file-already-exists)
@@ -2653,8 +2650,9 @@ This checks also `file-name-as-directory', `file-name-directory',
(skip-unless (tramp--test-enabled))
;; `filename-non-special' has been fixed in Emacs 27.1, see Bug#29579.
- (dolist (quoted (if (and (tramp--test-expensive-test) (tramp--test-emacs27-p))
- '(nil t) '(nil)))
+ (dolist (quoted
+ (if (and (tramp--test-expensive-test-p) (tramp--test-emacs27-p))
+ '(nil t) '(nil)))
(let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (tramp--test-make-temp-name nil quoted))
(tmp-name3 (tramp--test-make-temp-name 'local quoted)))
@@ -2684,7 +2682,7 @@ This checks also `file-name-as-directory', `file-name-directory',
(should (string-equal (buffer-string) "foo")))
(write-region "foo" nil source)
(should (file-exists-p source))
- (when (tramp--test-expensive-test)
+ (when (tramp--test-expensive-test-p)
(should-error
(rename-file source target)
:type 'file-already-exists))
@@ -2703,7 +2701,8 @@ This checks also `file-name-as-directory', `file-name-directory',
(make-directory target)
(should (file-directory-p target))
;; This has been changed in Emacs 26.1.
- (when (and (tramp--test-expensive-test) (tramp--test-emacs26-p))
+ (when (and (tramp--test-expensive-test-p)
+ (tramp--test-emacs26-p))
(should-error
(rename-file source target)
:type 'file-already-exists)
@@ -2771,7 +2770,7 @@ This checks also `file-name-as-directory', `file-name-directory',
This tests also `file-directory-p' and `file-accessible-directory-p'."
(skip-unless (tramp--test-enabled))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let* ((tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (expand-file-name "foo/bar" tmp-name1))
(unusual-file-mode-1 #o740)
@@ -2809,7 +2808,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
"Check `delete-directory'."
(skip-unless (tramp--test-enabled))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let* ((tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (expand-file-name "foo" tmp-name1)))
;; Delete empty directory.
@@ -2833,9 +2832,12 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(should-not (file-directory-p tmp-name1))
;; Trashing directories works only since Emacs 27.1. It doesn't
- ;; work on MS Windows, for crypted remote directories and for ange-ftp.
- (when (and (not (tramp--test-windows-nt-p)) (not (tramp--test-crypt-p))
- (not (tramp--test-ftp-p)) (tramp--test-emacs27-p))
+ ;; work when `system-move-file-to-trash' is defined (on MS
+ ;; Windows and macOS), for crypted remote directories and for
+ ;; ange-ftp.
+ (when (and (not (fboundp 'system-move-file-to-trash))
+ (not (tramp--test-crypt-p)) (not (tramp--test-ftp-p))
+ (tramp--test-emacs27-p))
(let ((trash-directory (tramp--test-make-temp-name 'local quoted))
(delete-by-moving-to-trash t))
(make-directory trash-directory)
@@ -2883,7 +2885,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
(skip-unless (tramp--test-enabled))
(skip-unless (or (tramp--test-emacs26-p) (not (tramp--test-rclone-p))))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let* ((tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (tramp--test-make-temp-name nil quoted))
(tmp-name3 (expand-file-name
@@ -2994,7 +2996,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
"Check `directory-files'."
(skip-unless (tramp--test-enabled))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let* ((tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (expand-file-name "bla" tmp-name1))
(tmp-name3 (expand-file-name "foo" tmp-name1)))
@@ -3038,7 +3040,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
"Check `file-expand-wildcards'."
(skip-unless (tramp--test-enabled))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let* ((tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (expand-file-name "foo" tmp-name1))
(tmp-name3 (expand-file-name "bar" tmp-name1))
@@ -3108,7 +3110,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
;; Emacs 27.1.
(skip-unless (or (not (tramp--test-crypt-p)) (tramp--test-emacs27-p)))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let* ((tmp-name1
(expand-file-name (tramp--test-make-temp-name nil quoted)))
(tmp-name2 (expand-file-name "foo" tmp-name1))
@@ -3193,7 +3195,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
;; Since Emacs 26.1.
(skip-unless (fboundp 'insert-directory-wildcard-in-dir-p))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let* ((tmp-name1
(expand-file-name (tramp--test-make-temp-name nil quoted)))
(tmp-name2
@@ -3297,7 +3299,7 @@ This tests also `file-directory-p' and `file-accessible-directory-p'."
;; Relative file names in dired are not supported in tramp-crypt.el.
(skip-unless (not (tramp--test-crypt-p)))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let* ((tmp-name1
(expand-file-name (tramp--test-make-temp-name nil quoted)))
(tmp-name2 (expand-file-name "foo" tmp-name1))
@@ -3351,7 +3353,7 @@ This tests also `access-file', `file-readable-p',
`file-regular-p' and `file-ownership-preserved-p'."
(skip-unless (tramp--test-enabled))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
;; We must use `file-truename' for the temporary directory,
;; because it could be located on a symlinked directory. This
;; would let the test fail.
@@ -3474,8 +3476,10 @@ This tests also `access-file', `file-readable-p',
(should
(string-equal
(tramp-compat-file-attribute-type attr)
- (tramp-file-name-localname
- (tramp-dissect-file-name tmp-name3))))
+ (funcall
+ (if (tramp--test-sshfs-p) #'file-name-nondirectory #'identity)
+ (tramp-file-name-localname
+ (tramp-dissect-file-name tmp-name3)))))
(delete-file tmp-name2))
(when test-file-ownership-preserved-p
@@ -3570,7 +3574,7 @@ They might differ only in time attributes or directory size."
"Check `directory-files-and-attributes'."
(skip-unless (tramp--test-enabled))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
;; `directory-files-and-attributes' contains also values for
;; "../". Ensure that this doesn't change during tests, for
;; example due to handling temporary files.
@@ -3628,7 +3632,7 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-supports-set-file-modes-p))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (tramp--test-make-temp-name nil quoted)))
@@ -3644,8 +3648,9 @@ This tests also `file-executable-p', `file-writable-p' and `set-file-modes'."
(should (= (file-modes tmp-name1) #o444))
(should-not (file-executable-p tmp-name1))
;; A file is always writable for user "root".
- (unless (zerop (tramp-compat-file-attribute-user-id
- (file-attributes tmp-name1)))
+ (unless (or (zerop (tramp-compat-file-attribute-user-id
+ (file-attributes tmp-name1)))
+ (tramp--test-sshfs-p))
(should-not (file-writable-p tmp-name1)))
;; Check the NOFOLLOW arg. It exists since Emacs 28. For
;; regular files, there shouldn't be a difference.
@@ -3723,7 +3728,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
;; older Emacsen, therefore.
(skip-unless (tramp--test-emacs26-p))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
;; We must use `file-truename' for the temporary directory,
;; because it could be located on a symlinked directory. This
;; would let the test fail.
@@ -3748,11 +3753,11 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(if quoted #'tramp-compat-file-name-unquote #'identity)
(file-remote-p tmp-name1 'localname))
(file-symlink-p tmp-name2)))
- (when (tramp--test-expensive-test)
+ (when (tramp--test-expensive-test-p)
(should-error
(make-symbolic-link tmp-name1 tmp-name2)
:type 'file-already-exists))
- (when (tramp--test-expensive-test)
+ (when (tramp--test-expensive-test-p)
;; A number means interactive case.
(cl-letf (((symbol-function #'yes-or-no-p) #'ignore))
(should-error
@@ -3792,7 +3797,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(string-equal tmp-name1 (file-symlink-p tmp-name3))))
;; Check directory as newname.
(make-directory tmp-name4)
- (when (tramp--test-expensive-test)
+ (when (tramp--test-expensive-test-p)
(should-error
(make-symbolic-link tmp-name1 tmp-name4)
:type 'file-already-exists))
@@ -3820,7 +3825,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
;; Check `add-name-to-file'.
(unwind-protect
- (when (tramp--test-expensive-test)
+ (when (tramp--test-expensive-test-p)
(tramp--test-ignore-add-name-to-file-error
(write-region "foo" nil tmp-name1)
(should (file-exists-p tmp-name1))
@@ -3935,11 +3940,11 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(string-equal
(file-truename tmp-name2)
(file-truename tmp-name3)))
- (when (tramp--test-expensive-test)
+ (when (tramp--test-expensive-test-p)
(should-error
(with-temp-buffer (insert-file-contents tmp-name2))
:type tramp-file-missing))
- (when (tramp--test-expensive-test)
+ (when (tramp--test-expensive-test-p)
(should-error
(with-temp-buffer (insert-file-contents tmp-name3))
:type tramp-file-missing))
@@ -3957,7 +3962,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
;; Detect cyclic symbolic links.
(unwind-protect
- (when (tramp--test-expensive-test)
+ (when (tramp--test-expensive-test-p)
(tramp--test-ignore-make-symbolic-link-error
(make-symbolic-link tmp-name2 tmp-name1)
(should (file-symlink-p tmp-name1))
@@ -3995,7 +4000,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(or (tramp--test-adb-p) (tramp--test-gvfs-p)
(tramp--test-sh-p) (tramp--test-sudoedit-p)))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (tramp--test-make-temp-name nil quoted))
(tmp-name3 (tramp--test-make-temp-name nil quoted)))
@@ -4045,7 +4050,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
"Check `set-visited-file-modtime' and `verify-visited-file-modtime'."
(skip-unless (tramp--test-enabled))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let ((tmp-name (tramp--test-make-temp-name nil quoted)))
(unwind-protect
(progn
@@ -4078,8 +4083,9 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(skip-unless (not (tramp--test-crypt-p)))
;; `filename-non-special' has been fixed in Emacs 27.1, see Bug#29579.
- (dolist (quoted (if (and (tramp--test-expensive-test) (tramp--test-emacs27-p))
- '(nil t) '(nil)))
+ (dolist (quoted
+ (if (and (tramp--test-expensive-test-p) (tramp--test-emacs27-p))
+ '(nil t) '(nil)))
(let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (tramp--test-make-temp-name nil quoted))
(tmp-name3 (tramp--test-make-temp-name 'local quoted)))
@@ -4157,8 +4163,9 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(skip-unless (not (tramp--test-crypt-p)))
;; `filename-non-special' has been fixed in Emacs 27.1, see Bug#29579.
- (dolist (quoted (if (and (tramp--test-expensive-test) (tramp--test-emacs27-p))
- '(nil t) '(nil)))
+ (dolist (quoted
+ (if (and (tramp--test-expensive-test-p) (tramp--test-emacs27-p))
+ '(nil t) '(nil)))
(let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (tramp--test-make-temp-name nil quoted))
(tmp-name3 (tramp--test-make-temp-name 'local quoted)))
@@ -4305,7 +4312,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(unwind-protect
(dolist
(syntax
- (if (tramp--test-expensive-test)
+ (if (tramp--test-expensive-test-p)
(tramp-syntax-values) `(,orig-syntax)))
(tramp-change-syntax syntax)
;; This has cleaned up all connection data, which are used
@@ -4347,7 +4354,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(tramp-change-syntax orig-syntax))))
(dolist (non-essential '(nil t))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let ((tmp-name (tramp--test-make-temp-name nil quoted)))
(unwind-protect
@@ -4414,7 +4421,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
"Check `load'."
(skip-unless (tramp--test-enabled))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let ((tmp-name (tramp--test-make-temp-name nil quoted)))
(unwind-protect
(progn
@@ -4443,10 +4450,11 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-supports-processes-p))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let* ((tmp-name (tramp--test-make-temp-name nil quoted))
(fnnd (file-name-nondirectory tmp-name))
(default-directory tramp-test-temporary-file-directory)
+ (buffer (get-buffer-create "*tramp-tests*"))
kill-buffer-query-functions)
(unwind-protect
(progn
@@ -4479,32 +4487,87 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(tramp--test-shell-file-name)
nil nil nil "-c" "kill -2 $$")))))
- (with-temp-buffer
- (write-region "foo" nil tmp-name)
- (should (file-exists-p tmp-name))
- (should (zerop (process-file "ls" nil t nil fnnd)))
- ;; "ls" could produce colorized output.
- (goto-char (point-min))
- (while
- (re-search-forward tramp-display-escape-sequence-regexp nil t)
- (replace-match "" nil nil))
- (should (string-equal (format "%s\n" fnnd) (buffer-string)))
- (should-not (get-buffer-window (current-buffer) t))
+ ;; Check DESTINATION.
+ (dolist (destination `(nil t ,buffer))
+ (when (bufferp destination)
+ (with-current-buffer destination
+ (delete-region (point-min) (point-max))))
+ (with-temp-buffer
+ (write-region "foo" nil tmp-name)
+ (should (file-exists-p tmp-name))
+ (should (zerop (process-file "ls" nil destination nil fnnd)))
+ (with-current-buffer
+ (if (bufferp destination) destination (current-buffer))
+ ;; "ls" could produce colorized output.
+ (goto-char (point-min))
+ (while (re-search-forward
+ tramp-display-escape-sequence-regexp nil t)
+ (replace-match "" nil nil))
+ (should
+ (string-equal (if destination (format "%s\n" fnnd) "")
+ (buffer-string)))
+ (should-not (get-buffer-window (current-buffer) t))
+ (goto-char (point-max)))
+
+ ;; Second run. The output must be appended.
+ (should (zerop (process-file "ls" nil destination t fnnd)))
+ (with-current-buffer
+ (if (bufferp destination) destination (current-buffer))
+ ;; "ls" could produce colorized output.
+ (goto-char (point-min))
+ (while (re-search-forward
+ tramp-display-escape-sequence-regexp nil t)
+ (replace-match "" nil nil))
+ (should
+ (string-equal
+ (if destination (format "%s\n%s\n" fnnd fnnd) "")
+ (buffer-string))))
- ;; Second run. The output must be appended.
- (goto-char (point-max))
- (should (zerop (process-file "ls" nil t t fnnd)))
- ;; "ls" could produce colorized output.
- (goto-char (point-min))
- (while
- (re-search-forward tramp-display-escape-sequence-regexp nil t)
- (replace-match "" nil nil))
- (should
- (string-equal (format "%s\n%s\n" fnnd fnnd) (buffer-string)))
- ;; A non-nil DISPLAY must not raise the buffer.
- (should-not (get-buffer-window (current-buffer) t))))
+ (unless (eq destination t)
+ (should (string-empty-p (buffer-string))))
+ ;; A non-nil DISPLAY must not raise the buffer.
+ (should-not (get-buffer-window (current-buffer) t))
+ (delete-file tmp-name)))
+
+ ;; Check remote and local INFILE.
+ (dolist (local '(nil t))
+ (with-temp-buffer
+ (setq tmp-name (tramp--test-make-temp-name local quoted))
+ (write-region "foo" nil tmp-name)
+ (should (file-exists-p tmp-name))
+ (should (zerop (process-file "cat" tmp-name t)))
+ (should (string-equal "foo" (buffer-string)))
+ (should-not (get-buffer-window (current-buffer) t))
+ (delete-file tmp-name)))
+
+ ;; Check remote and local DESTNATION file. This isn't
+ ;; implemented yet ina all file name handler backends.
+ ;; (dolist (local '(nil t))
+ ;; (setq tmp-name (tramp--test-make-temp-name local quoted))
+ ;; (should
+ ;; (zerop (process-file "echo" nil `(:file ,tmp-name) nil "foo")))
+ ;; (with-temp-buffer
+ ;; (insert-file-contents tmp-name)
+ ;; (should (string-equal "foo" (buffer-string)))
+ ;; (should-not (get-buffer-window (current-buffer) t))
+ ;; (delete-file tmp-name)))
+
+ ;; Check remote and local STDERR.
+ (dolist (local '(nil t))
+ (setq tmp-name (tramp--test-make-temp-name local quoted))
+ (should-not
+ (zerop
+ (process-file "cat" nil `(t ,tmp-name) nil "/does-not-exist")))
+ (with-temp-buffer
+ (insert-file-contents tmp-name)
+ (should
+ (string-match-p
+ "cat:.* No such file or directory" (buffer-string)))
+ (should-not (get-buffer-window (current-buffer) t))
+ (delete-file tmp-name))))
;; Cleanup.
+ (ignore-errors (kill-buffer buffer))
(ignore-errors (delete-file tmp-name))))))
;; Must be a command, because used as `sigusr1' handler.
@@ -4519,11 +4582,11 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(ert-deftest tramp-test29-start-file-process ()
"Check `start-file-process'."
- :tags '(:expensive-test)
+ :tags '(:expensive-test :tramp-asynchronous-processes)
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-supports-processes-p))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let ((default-directory tramp-test-temporary-file-directory)
(tmp-name (tramp--test-make-temp-name nil quoted))
kill-buffer-query-functions proc)
@@ -4586,8 +4649,8 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
;; Cleanup.
(ignore-errors (delete-process proc)))
- ;; "telnet" and "sshfs" do not cooperate with disabled filter.
- (unless (or (tramp--test-telnet-p) (tramp--test-sshfs-p))
+ ;; Disabled process filter. "sshfs" does not cooperate.
+ (unless (tramp--test-sshfs-p)
(unwind-protect
(with-temp-buffer
(setq proc (start-file-process "test3" (current-buffer) "cat"))
@@ -4596,8 +4659,8 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'."
(set-process-filter proc t)
(process-send-string proc "foo\n")
(process-send-eof proc)
- ;; Read output.
- (with-timeout (10 (tramp--test-timeout-handler))
+ ;; Read output. There shouldn't be any.
+ (with-timeout (10)
(while (process-live-p proc)
(while (accept-process-output proc 0 nil t))))
;; No output due to process filter.
@@ -4675,7 +4738,8 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(ignore-errors (make-process :file-handler t)))
`(ert-deftest ,(intern (concat (symbol-name test) "-direct-async")) ()
,docstring
- :tags (if ,unstable '(:expensive-test :unstable) '(:expensive-test))
+ :tags (append '(:expensive-test :tramp-asynchronous-processes)
+ (and ,unstable '(:unstable)))
(skip-unless (tramp--test-enabled))
(let ((default-directory tramp-test-temporary-file-directory)
(ert-test (ert-get-test ',test))
@@ -4698,13 +4762,15 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(ert-deftest tramp-test30-make-process ()
"Check `make-process'."
- :tags '(:expensive-test)
+ :tags (append '(:expensive-test :tramp-asynchronous-processes)
+ (and (getenv "EMACS_EMBA_CI")
+ '(:unstable)))
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-supports-processes-p))
;; `make-process' supports file name handlers since Emacs 27.
(skip-unless (tramp--test-emacs27-p))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let ((default-directory tramp-test-temporary-file-directory)
(tmp-name (tramp--test-make-temp-name nil quoted))
kill-buffer-query-functions proc)
@@ -4778,8 +4844,8 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
;; Cleanup.
(ignore-errors (delete-process proc)))
- ;; "telnet" and "sshfs" do not cooperate with disabled filter.
- (unless (or (tramp--test-telnet-p) (tramp--test-sshfs-p))
+ ;; Disabled process filter. "sshfs" does not cooperate.
+ (unless (tramp--test-sshfs-p)
(unwind-protect
(with-temp-buffer
(setq proc
@@ -4792,8 +4858,8 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(should (equal (process-status proc) 'run))
(process-send-string proc "foo\n")
(process-send-eof proc)
- ;; Read output.
- (with-timeout (10 (tramp--test-timeout-handler))
+ ;; Read output. There shouldn't be any.
+ (with-timeout (10)
(while (process-live-p proc)
(while (accept-process-output proc 0 nil t))))
;; No output due to process filter.
@@ -4941,8 +5007,9 @@ If UNSTABLE is non-nil, the test is tagged as `:unstable'."
(ert-deftest tramp-test31-interrupt-process ()
"Check `interrupt-process'."
- :tags (if (or (getenv "EMACS_HYDRA_CI") (getenv "EMACS_EMBA_CI"))
- '(:expensive-test :unstable) '(:expensive-test))
+ :tags (append '(:expensive-test :tramp-asynchronous-processes)
+ (and (or (getenv "EMACS_HYDRA_CI") (getenv "EMACS_EMBA_CI"))
+ '(:unstable)))
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-crypt-p)))
@@ -5009,7 +5076,7 @@ INPUT, if non-nil, is a string sent to the process."
(when (tramp--test-adb-p)
(skip-unless (tramp--test-emacs27-p)))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let ((tmp-name (tramp--test-make-temp-name nil quoted))
(default-directory tramp-test-temporary-file-directory)
;; Suppress nasty messages.
@@ -5017,10 +5084,12 @@ INPUT, if non-nil, is a string sent to the process."
kill-buffer-query-functions)
(dolist (this-shell-command
- '(;; Synchronously.
- shell-command
- ;; Asynchronously.
- tramp--test-async-shell-command))
+ (append
+ ;; Synchronously.
+ '(shell-command)
+ ;; Asynchronously.
+ (and (tramp--test-asynchronous-processes-p)
+ '(tramp--test-async-shell-command))))
;; Test ordinary `{async-}shell-command'.
(unwind-protect
@@ -5061,31 +5130,34 @@ INPUT, if non-nil, is a string sent to the process."
(ignore-errors (kill-buffer stderr))))))
;; Test sending string to `async-shell-command'.
- (unwind-protect
- (with-temp-buffer
- (write-region "foo" nil tmp-name)
- (should (file-exists-p tmp-name))
- (tramp--test-async-shell-command
- "read line; ls $line" (current-buffer) nil
- ;; String to be sent.
- (format "%s\n" (file-name-nondirectory tmp-name)))
- (should
- (string-equal
- ;; tramp-adb.el echoes, so we must add the string.
- (if (and (tramp--test-adb-p) (not (tramp-direct-async-process-p)))
- (format
- "%s\n%s\n"
- (file-name-nondirectory tmp-name)
- (file-name-nondirectory tmp-name))
- (format "%s\n" (file-name-nondirectory tmp-name)))
- (buffer-string))))
+ (when (tramp--test-asynchronous-processes-p)
+ (unwind-protect
+ (with-temp-buffer
+ (write-region "foo" nil tmp-name)
+ (should (file-exists-p tmp-name))
+ (tramp--test-async-shell-command
+ "read line; ls $line" (current-buffer) nil
+ ;; String to be sent.
+ (format "%s\n" (file-name-nondirectory tmp-name)))
+ (should
+ (string-equal
+ ;; tramp-adb.el echoes, so we must add the string.
+ (if (and (tramp--test-adb-p)
+ (not (tramp-direct-async-process-p)))
+ (format
+ "%s\n%s\n"
+ (file-name-nondirectory tmp-name)
+ (file-name-nondirectory tmp-name))
+ (format "%s\n" (file-name-nondirectory tmp-name)))
+ (buffer-string))))
- ;; Cleanup.
- (ignore-errors (delete-file tmp-name)))))
+ ;; Cleanup.
+ (ignore-errors (delete-file tmp-name))))))
;; Test `async-shell-command-width'. It exists since Emacs 26.1,
;; but seems to work since Emacs 27.1 only.
- (when (and (tramp--test-sh-p) (tramp--test-emacs27-p))
+ (when (and (tramp--test-asynchronous-processes-p)
+ (tramp--test-sh-p) (tramp--test-emacs27-p))
(let* ((async-shell-command-width 1024)
(default-directory tramp-test-temporary-file-directory)
(cols (ignore-errors
@@ -5232,10 +5304,12 @@ INPUT, if non-nil, is a string sent to the process."
(skip-unless (not (tramp--test-crypt-p)))
(dolist (this-shell-command-to-string
- '(;; Synchronously.
- shell-command-to-string
- ;; Asynchronously.
- tramp--test-shell-command-to-string-asynchronously))
+ (append
+ ;; Synchronously.
+ '(shell-command-to-string)
+ ;; Asynchronously.
+ (and (tramp--test-asynchronous-processes-p)
+ '(tramp--test-shell-command-to-string-asynchronously))))
(let ((default-directory tramp-test-temporary-file-directory)
(shell-file-name "/bin/sh")
@@ -5424,7 +5498,7 @@ Use direct async.")
;; The functions were introduced in Emacs 26.1.
(ert-deftest tramp-test34-explicit-shell-file-name ()
"Check that connection-local `explicit-shell-file-name' is set."
- :tags '(:expensive-test)
+ :tags '(:expensive-test :tramp-asynchronous-processes)
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-supports-processes-p))
;; Prior Emacs 27, `shell-file-name' was hard coded as "/bin/sh" for
@@ -5598,7 +5672,7 @@ Use direct async.")
(skip-unless (tramp--test-sh-p))
(skip-unless (not (tramp--test-crypt-p)))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
;; We must use `file-truename' for the temporary directory, in
;; order to establish the connection prior running an asynchronous
;; process.
@@ -5668,7 +5742,7 @@ Use direct async.")
"Check `make-auto-save-file-name'."
(skip-unless (tramp--test-enabled))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (tramp--test-make-temp-name nil quoted))
tramp-allow-unsafe-temporary-files)
@@ -5791,7 +5865,7 @@ Use direct async.")
"Check `find-backup-file-name'."
(skip-unless (tramp--test-enabled))
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (tramp--test-make-temp-name nil quoted))
(ange-ftp-make-backup-files t)
@@ -5943,7 +6017,7 @@ Use direct async.")
;; `lock-file', `unlock-file', `file-locked-p' and
;; `make-lock-file-name' exists since Emacs 28.1. We don't want to
;; see compiler warnings for older Emacsen.
- (dolist (quoted (if (tramp--test-expensive-test) '(nil t) '(nil)))
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
(let ((tmp-name1 (tramp--test-make-temp-name nil quoted))
(tmp-name2 (tramp--test-make-temp-name nil quoted))
(remote-file-name-inhibit-cache t)
@@ -6064,6 +6138,79 @@ Use direct async.")
(ignore-errors (delete-file tmp-name1))
(tramp-cleanup-connection tramp-test-vec 'keep-debug 'keep-password)))))
+;; The functions were introduced in Emacs 28.1.
+(ert-deftest tramp-test39-detect-external-change ()
+ "Check that an external file modification is reported."
+ (skip-unless (tramp--test-enabled))
+ (skip-unless (not (tramp--test-ange-ftp-p)))
+ ;; Since Emacs 28.1.
+ (skip-unless (and (fboundp 'lock-file) (fboundp 'file-locked-p)))
+
+ (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil)))
+ (dolist (create-lockfiles '(nil t))
+ (let ((tmp-name (tramp--test-make-temp-name nil quoted))
+ (remote-file-name-inhibit-cache t)
+ (remote-file-name-inhibit-locks nil)
+ tramp-allow-unsafe-temporary-files
+ (inhibit-message t)
+ ;; tramp-rclone.el and tramp-sshfs.el cache the mounted files.
+ (tramp-fuse-unmount-on-cleanup t)
+ auto-save-default
+ (backup-inhibited t)
+ noninteractive)
+ (with-temp-buffer
+ (unwind-protect
+ (progn
+ (setq buffer-file-name tmp-name
+ buffer-file-truename tmp-name)
+ (insert "foo")
+ ;; Bug#53207: with `create-lockfiles' nil, saving the
+ ;; buffer results in a prompt.
+ (cl-letf (((symbol-function 'yes-or-no-p)
+ (lambda (_) (ert-fail "Test failed unexpectedly"))))
+ (save-buffer))
+ (should-not (file-locked-p tmp-name))
+
+ ;; Macro `ert-with-message-capture' was introduced in Emacs 26.1.
+ (with-no-warnings (when (symbol-plist 'ert-with-message-capture)
+ ;; For local files, just changing the file
+ ;; modification on disk doesn't hurt, because file
+ ;; contents in buffer and on disk are equal. For
+ ;; remote files, file contents is not compared. We
+ ;; mock an older modification time in buffer,
+ ;; because Tramp regards modification times equal if
+ ;; they differ for less than 2 seconds.
+ (set-visited-file-modtime (time-add (current-time) -60))
+ ;; Some Tramp methods cannot check the file
+ ;; modification time properly, for them it doesn't
+ ;; make sense to test.
+ (when (not (verify-visited-file-modtime))
+ (cl-letf (((symbol-function 'read-char-choice)
+ (lambda (prompt &rest _) (message "%s" prompt) ?y)))
+ (ert-with-message-capture captured-messages
+ (insert "bar")
+ (when create-lockfiles
+ (should (string-match-p
+ (format
+ "^%s changed on disk; really edit the buffer\\?"
+ (if (tramp--test-crypt-p)
+ ".+" (file-name-nondirectory tmp-name)))
+ captured-messages))
+ (should (file-locked-p tmp-name)))))
+
+ ;; `save-buffer' removes the file lock.
+ (cl-letf (((symbol-function 'yes-or-no-p) #'tramp--test-always)
+ ((symbol-function 'read-char-choice)
+ (lambda (&rest _) ?y)))
+ (save-buffer))
+ (should-not (file-locked-p tmp-name))))))
+
+ ;; Cleanup.
+ (set-buffer-modified-p nil)
+ (ignore-errors (delete-file tmp-name))
+ (tramp-cleanup-connection
+ tramp-test-vec 'keep-debug 'keep-password)))))))
+
;; The functions were introduced in Emacs 26.1.
(ert-deftest tramp-test40-make-nearby-temp-file ()
"Check `make-nearby-temp-file' and `temporary-file-directory'."
@@ -6131,6 +6278,19 @@ This requires restrictions of file name syntax."
(tramp-find-foreign-file-name-handler tramp-test-temporary-file-directory)
'tramp-ftp-file-name-handler))
+(defun tramp--test-asynchronous-processes-p ()
+ "Whether asynchronous processes tests are run.
+This is used in tests which we dont't want to tag
+`:tramp-asynchronous-processes' completely."
+ (and
+ (ert-select-tests
+ (ert--stats-selector ert--current-run-stats)
+ (list (make-ert-test :name (ert-test-name (ert-running-test))
+ :body nil :tags '(:tramp-asynchronous-processes))))
+ ;; tramp-adb.el cannot apply multi-byte commands.
+ (not (and (tramp--test-adb-p)
+ (string-match-p "[[:multibyte:]]" default-directory)))))
+
(defun tramp--test-crypt-p ()
"Check, whether the remote directory is crypted."
(tramp-crypt-file-name-p tramp-test-temporary-file-directory))
@@ -6141,6 +6301,15 @@ This does not support some special file names."
(string-equal
"docker" (file-remote-p tramp-test-temporary-file-directory 'method)))
+(defun tramp--test-expensive-test-p ()
+ "Whether expensive tests are run.
+This is used in tests which we dont't want to tag `:expensive'
+completely."
+ (ert-select-tests
+ (ert--stats-selector ert--current-run-stats)
+ (list (make-ert-test :name (ert-test-name (ert-running-test))
+ :body nil :tags '(:expensive-test)))))
+
(defun tramp--test-ftp-p ()
"Check, whether an FTP-like method is used.
This does not support globbing characters in file names (yet)."
@@ -6169,7 +6338,7 @@ If optional METHOD is given, it is checked first."
Several special characters do not work properly there."
;; We must refill the cache. `file-truename' does it.
(file-truename tramp-test-temporary-file-directory)
- (tramp-check-remote-uname tramp-test-vec "^HP-UX"))
+ (ignore-errors (tramp-check-remote-uname tramp-test-vec "^HP-UX")))
(defun tramp--test-ksh-p ()
"Check, whether the remote shell is ksh.
@@ -6184,7 +6353,7 @@ a $'' syntax."
"Check, whether the remote host runs macOS."
;; We must refill the cache. `file-truename' does it.
(file-truename tramp-test-temporary-file-directory)
- (tramp-check-remote-uname tramp-test-vec "Darwin"))
+ (ignore-errors (tramp-check-remote-uname tramp-test-vec "Darwin")))
(defun tramp--test-mock-p ()
"Check, whether the mock method is used.
@@ -6284,8 +6453,9 @@ This requires restrictions of file name syntax."
(defun tramp--test-check-files (&rest files)
"Run a simple but comprehensive test over every file in FILES."
;; `filename-non-special' has been fixed in Emacs 27.1, see Bug#29579.
- (dolist (quoted (if (and (tramp--test-expensive-test) (tramp--test-emacs27-p))
- '(nil t) '(nil)))
+ (dolist (quoted
+ (if (and (tramp--test-expensive-test-p) (tramp--test-emacs27-p))
+ '(nil t) '(nil)))
;; We must use `file-truename' for the temporary directory,
;; because it could be located on a symlinked directory. This
;; would let the test fail.
@@ -6437,6 +6607,31 @@ This requires restrictions of file name syntax."
(delete-file file3)
(should-not (file-exists-p file3))))
+ ;; Check, that a process runs on a remote
+ ;; `default-directory' with special characters. See
+ ;; Bug#53846.
+ (when (and (tramp--test-expensive-test-p)
+ (tramp--test-supports-processes-p)
+ ;; Prior Emacs 27, `shell-file-name' was
+ ;; hard coded as "/bin/sh" for remote
+ ;; processes in Emacs. That doesn't work
+ ;; for tramp-adb.el. tramp-sshfs.el times
+ ;; out for older Emacsen, reason unknown.
+ (or (and (not (tramp--test-adb-p))
+ (not (tramp--test-sshfs-p)))
+ (tramp--test-emacs27-p)))
+ (let ((default-directory file1))
+ (dolist (this-shell-command
+ (append
+ ;; Synchronously.
+ '(shell-command)
+ ;; Asynchronously.
+ (and (tramp--test-asynchronous-processes-p)
+ '(tramp--test-async-shell-command))))
+ (with-temp-buffer
+ (funcall this-shell-command "cat -- *" (current-buffer))
+ (should (string-equal elt (buffer-string)))))))
+
(delete-file file2)
(should-not (file-exists-p file2))
(delete-directory file1)
@@ -6445,7 +6640,7 @@ This requires restrictions of file name syntax."
;; Check, that environment variables are set correctly.
;; We do not run on macOS due to encoding problems. See
;; Bug#36940.
- (when (and (tramp--test-expensive-test) (tramp--test-sh-p)
+ (when (and (tramp--test-expensive-test-p) (tramp--test-sh-p)
(not (tramp--test-crypt-p))
(not (eq system-type 'darwin)))
(dolist (elt files)
@@ -6506,7 +6701,7 @@ This requires restrictions of file name syntax."
(unless (or (tramp--test-ftp-p)
(tramp--test-gvfs-p)
(tramp--test-windows-nt-or-smb-p))
- "*foo*bar*baz*")
+ "*foo+bar*baz+")
(if (or (tramp--test-gvfs-p) (tramp--test-windows-nt-or-smb-p))
"'foo'bar'baz'"
"'foo\"bar'baz\"")
@@ -6527,7 +6722,7 @@ This requires restrictions of file name syntax."
"{foo}bar{baz}")))
;; Simplify test in order to speed up.
(apply #'tramp--test-check-files
- (if (tramp--test-expensive-test)
+ (if (tramp--test-expensive-test-p)
files (list (mapconcat #'identity files ""))))))
;; These tests are inspired by Bug#17238.
@@ -6626,7 +6821,7 @@ Use the \"ls\" command."
;; to U+1FFFF).
"🌈🍒👋")
- (when (tramp--test-expensive-test)
+ (when (tramp--test-expensive-test-p)
(delete-dups
(mapcar
;; Use all available language specific snippets.
@@ -6798,8 +6993,10 @@ This is needed in timer functions as well as process filters and sentinels."
"Check parallel asynchronous requests.
Such requests could arrive from timers, process filters and
process sentinels. They shall not disturb each other."
- :tags (if (getenv "EMACS_EMBA_CI")
- '(:expensive-test :unstable) '(:expensive-test))
+ :tags (append '(:expensive-test :tramp-asynchronous-processes)
+ (and (or (getenv "EMACS_HYDRA_CI")
+ (getenv "EMACS_EMBA_CI"))
+ '(:unstable)))
(skip-unless (tramp--test-enabled))
(skip-unless (tramp--test-supports-processes-p))
;; Prior Emacs 27, `shell-file-name' was hard coded as "/bin/sh" for
@@ -7113,7 +7310,6 @@ process sentinels. They shall not disturb each other."
"Check that Tramp and its subpackages unload completely.
Since it unloads Tramp, it shall be the last test to run."
:tags '(:expensive-test)
- (skip-unless noninteractive)
;; The autoloaded Tramp objects are different since Emacs 26.1. We
;; cannot test older Emacsen, therefore.
(skip-unless (tramp--test-emacs26-p))
@@ -7126,28 +7322,34 @@ Since it unloads Tramp, it shall be the last test to run."
(should (featurep 'tramp-archive))
;; This unloads also tramp-archive.el and tramp-theme.el if needed.
(unload-feature 'tramp 'force)
- ;; No Tramp feature must be left.
+
+ ;; No Tramp feature must be left except the test packages.
(should-not (featurep 'tramp))
(should-not (featurep 'tramp-archive))
(should-not (featurep 'tramp-theme))
(should-not
(all-completions
"tramp" (delq 'tramp-tests (delq 'tramp-archive-tests features))))
+
;; `file-name-handler-alist' must be clean.
(should-not (all-completions "tramp" (mapcar #'cdr file-name-handler-alist)))
+
;; There shouldn't be left a bound symbol, except buffer-local
- ;; variables, and autoload functions. We do not regard our test
+ ;; variables, and autoloaded functions. We do not regard our test
;; symbols, and the Tramp unload hooks.
(mapatoms
(lambda (x)
(and (or (and (boundp x) (null (local-variable-if-set-p x)))
- (and (functionp x) (null (autoloadp (symbol-function x)))))
+ (and (functionp x) (null (autoloadp (symbol-function x))))
+ (macrop x))
(string-match-p "^tramp" (symbol-name x))
;; `tramp-completion-mode' is autoloaded in Emacs < 28.1.
(not (eq 'tramp-completion-mode x))
(not (string-match-p "^tramp\\(-archive\\)?--?test" (symbol-name x)))
(not (string-match-p "unload-hook$" (symbol-name x)))
+ (not (get x 'tramp-autoload))
(ert-fail (format "`%s' still bound" x)))))
+
;; The defstruct `tramp-file-name' and all its internal functions
;; shall be purged.
(should-not (cl--find-class 'tramp-file-name))
@@ -7156,6 +7358,7 @@ Since it unloads Tramp, it shall be the last test to run."
(and (functionp x)
(string-match-p "tramp-file-name" (symbol-name x))
(ert-fail (format "Structure function `%s' still exists" x)))))
+
;; There shouldn't be left a hook function containing a Tramp
;; function. We do not regard the Tramp unload hooks.
(mapatoms
@@ -7165,7 +7368,24 @@ Since it unloads Tramp, it shall be the last test to run."
(not (string-match-p "unload-hook$" (symbol-name x)))
(consp (symbol-value x))
(ignore-errors (all-completions "tramp" (symbol-value x)))
- (ert-fail (format "Hook `%s' still contains Tramp function" x))))))
+ (ert-fail (format "Hook `%s' still contains Tramp function" x)))))
+
+ ;; There shouldn't be left an advice function from Tramp.
+ (mapatoms
+ (lambda (x)
+ (and (functionp x)
+ (advice-mapc
+ (lambda (fun _symbol)
+ (and (string-match-p "^tramp" (symbol-name fun))
+ (ert-fail
+ (format "Function `%s' still contains Tramp advice" x))))
+ x))))
+
+ ;; Reload.
+ (require 'tramp)
+ (require 'tramp-archive)
+ (should (featurep 'tramp))
+ (should (featurep 'tramp-archive)))
(defun tramp-test-all (&optional interactive)
"Run all tests for \\[tramp].
commit 4161a368499a3326d13113aa5c6ab332047df767
Author: Stefan Monnier
Date: Wed Jan 5 14:28:08 2022 -0500
cl-generic.el: Fix bug#46722
Fix longstanding bug due to unexpected interference via side-effect.
* lisp/emacs-lisp/cl-generic.el (cl--generic-get-dispatcher):
Copy the `dispatch` arg before storing it into the hash-table.
Backport from `master` (cherrypick from commit 61f8f7f68f).
diff --git a/lisp/emacs-lisp/cl-generic.el b/lisp/emacs-lisp/cl-generic.el
index a7e24236a3..add8e7fda0 100644
--- a/lisp/emacs-lisp/cl-generic.el
+++ b/lisp/emacs-lisp/cl-generic.el
@@ -602,7 +602,9 @@ The set of acceptable TYPEs (also called \"specializers\") is defined
(defun cl--generic-get-dispatcher (dispatch)
(cl--generic-with-memoization
- (gethash dispatch cl--generic-dispatchers)
+ ;; We need `copy-sequence` here because this `dispatch' object might be
+ ;; modified by side-effect in `cl-generic-define-method' (bug#46722).
+ (gethash (copy-sequence dispatch) cl--generic-dispatchers)
;; (message "cl--generic-get-dispatcher (%S)" dispatch)
(let* ((dispatch-arg (car dispatch))
(generalizers (cdr dispatch))
commit 8c71ac606ec484d5e9cf967b41aadbddb5c8b694
Author: Eli Zaretskii
Date: Tue Apr 5 21:15:32 2022 +0300
Fix fallout from lexical-binding in vhdl-mode.el
* lisp/progmodes/vhdl-mode.el (vhdl-update-sensitivity-list): Fix
production of a list with embedded function calls. (Bug#54730)
diff --git a/lisp/progmodes/vhdl-mode.el b/lisp/progmodes/vhdl-mode.el
index 64ebc14167..e562a463e1 100644
--- a/lisp/progmodes/vhdl-mode.el
+++ b/lisp/progmodes/vhdl-mode.el
@@ -8396,30 +8396,30 @@ buffer."
((visible-list (vhdl-get-visible-signals))
;; define syntactic regions where signals are read
(scan-regions-list
- '(;; right-hand side of signal/variable assignment
+ `(;; right-hand side of signal/variable assignment
;; (special case: "<=" is relational operator in a condition)
- ((vhdl-re-search-forward "[<:]=" proc-end t)
- (vhdl-re-search-forward ";\\|\\<\\(then\\|loop\\|report\\|severity\\|is\\)\\>" proc-end t))
+ ((vhdl-re-search-forward "[<:]=" ,proc-end t)
+ (vhdl-re-search-forward ";\\|\\<\\(then\\|loop\\|report\\|severity\\|is\\)\\>" ,proc-end t))
;; if condition
- ((vhdl-re-search-forward "^\\s-*if\\>" proc-end t)
- (vhdl-re-search-forward "\\" proc-end t))
+ ((vhdl-re-search-forward "^\\s-*if\\>" ,proc-end t)
+ (vhdl-re-search-forward "\\" ,proc-end t))
;; elsif condition
- ((vhdl-re-search-forward "\\" proc-end t)
- (vhdl-re-search-forward "\\" proc-end t))
+ ((vhdl-re-search-forward "\\" ,proc-end t)
+ (vhdl-re-search-forward "\\" ,proc-end t))
;; while loop condition
- ((vhdl-re-search-forward "^\\s-*while\\>" proc-end t)
- (vhdl-re-search-forward "\\" proc-end t))
+ ((vhdl-re-search-forward "^\\s-*while\\>" ,proc-end t)
+ (vhdl-re-search-forward "\\" ,proc-end t))
;; exit/next condition
- ((vhdl-re-search-forward "\\<\\(exit\\|next\\)\\s-+\\w+\\s-+when\\>" proc-end t)
- (vhdl-re-search-forward ";" proc-end t))
+ ((vhdl-re-search-forward "\\<\\(exit\\|next\\)\\s-+\\w+\\s-+when\\>" ,proc-end t)
+ (vhdl-re-search-forward ";" ,proc-end t))
;; assert condition
- ((vhdl-re-search-forward "\\" proc-end t)
- (vhdl-re-search-forward "\\(\\\\|\\\\|;\\)" proc-end t))
+ ((vhdl-re-search-forward "\\" ,proc-end t)
+ (vhdl-re-search-forward "\\(\\\\|\\\\|;\\)" ,proc-end t))
;; case expression
- ((vhdl-re-search-forward "^\\s-*case\\>" proc-end t)
- (vhdl-re-search-forward "\\" proc-end t))
+ ((vhdl-re-search-forward "^\\s-*case\\>" ,proc-end t)
+ (vhdl-re-search-forward "\\" ,proc-end t))
;; parameter list of procedure call, array index
- ((and (re-search-forward "^\\s-*\\(\\w\\|\\.\\)+[ \t\n\r\f]*(" proc-end t)
+ ((and (re-search-forward "^\\s-*\\(\\w\\|\\.\\)+[ \t\n\r\f]*(" ,proc-end t)
(1- (point)))
(progn (backward-char) (forward-sexp)
(while (looking-at "(") (forward-sexp)) (point)))))
commit dd3863d8bcc77c43363bbd041da1c1eb37a3ee32
Author: Eli Zaretskii
Date: Sun Apr 3 16:09:11 2022 +0300
; Prepare the release branch for Emacs-28.2 development
* README:
* configure.ac:
* nt/README.W32:
* msdos/sed2v2.inp: Bump Emacs version to 28.1.50.
* etc/NEWS: Add Emacs-28.2 sections.
diff --git a/README b/README
index 5e7cadeaa0..559c8aeca0 100644
--- a/README
+++ b/README
@@ -2,7 +2,7 @@ Copyright (C) 2001-2022 Free Software Foundation, Inc.
See the end of the file for license conditions.
-This directory tree holds version 28.1 of GNU Emacs, the extensible,
+This directory tree holds version 28.1.50 of GNU Emacs, the extensible,
customizable, self-documenting real-time display editor.
The file INSTALL in this directory says how to build and install GNU
diff --git a/configure.ac b/configure.ac
index 660784347b..7314eb6978 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,7 +23,7 @@ dnl along with GNU Emacs. If not, see .
AC_PREREQ(2.65)
dnl Note this is parsed by (at least) make-dist and lisp/cedet/ede/emacs.el.
-AC_INIT(GNU Emacs, 28.1, bug-gnu-emacs@gnu.org, , https://www.gnu.org/software/emacs/)
+AC_INIT(GNU Emacs, 28.1.50, bug-gnu-emacs@gnu.org, , https://www.gnu.org/software/emacs/)
dnl Set emacs_config_options to the options of 'configure', quoted for the shell,
dnl and then quoted again for a C string. Separate options with spaces.
diff --git a/etc/NEWS b/etc/NEWS
index 995de8d317..7fb8e8dce8 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -15,6 +15,33 @@ in older Emacs versions.
You can narrow news to a specific version by calling 'view-emacs-news'
with a prefix argument or by typing 'C-u C-h C-n'.
+
+* Installation Changes in Emacs 28.2
+
+
+* Startup Changes in Emacs 28.2
+
+
+* Changes in Emacs 28.2
+
+
+* Editing Changes in Emacs 28.2
+
+
+* Changes in Specialized Modes and Packages in Emacs 28.2
+
+
+* New Modes and Packages in Emacs 28.2
+
+
+* Incompatible Lisp Changes in Emacs 28.2
+
+
+* Lisp Changes in Emacs 28.2
+
+
+* Changes in Emacs 28.2 on Non-Free Operating Systems
+
* Installation Changes in Emacs 28.1
diff --git a/msdos/sed2v2.inp b/msdos/sed2v2.inp
index 6f57ad3181..fedccef4ef 100644
--- a/msdos/sed2v2.inp
+++ b/msdos/sed2v2.inp
@@ -67,7 +67,7 @@
/^#undef PACKAGE_NAME/s/^.*$/#define PACKAGE_NAME ""/
/^#undef PACKAGE_STRING/s/^.*$/#define PACKAGE_STRING ""/
/^#undef PACKAGE_TARNAME/s/^.*$/#define PACKAGE_TARNAME ""/
-/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "28.1"/
+/^#undef PACKAGE_VERSION/s/^.*$/#define PACKAGE_VERSION "28.1.50"/
/^#undef SYSTEM_TYPE/s/^.*$/#define SYSTEM_TYPE "ms-dos"/
/^#undef HAVE_DECL_GETENV/s/^.*$/#define HAVE_DECL_GETENV 1/
/^#undef SYS_SIGLIST_DECLARED/s/^.*$/#define SYS_SIGLIST_DECLARED 1/
diff --git a/nt/README.W32 b/nt/README.W32
index 94f538aa91..f0a8c8c326 100644
--- a/nt/README.W32
+++ b/nt/README.W32
@@ -1,7 +1,7 @@
Copyright (C) 2001-2022 Free Software Foundation, Inc.
See the end of the file for license conditions.
- Emacs version 28.1 for MS-Windows
+ Emacs version 28.1.50 for MS-Windows
This README file describes how to set up and run a precompiled
distribution of the latest version of GNU Emacs for MS-Windows. You