summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2022-01-16 15:58:41 -0700
committerSean Whitton <spwhitton@spwhitton.name>2022-01-16 15:58:41 -0700
commit574d33b4737cf0829eb85c802710bfc42093f6d1 (patch)
tree32d9bdcfd80db07cae90485c658841d1c0d025a6
parentbe8c25fd3dacc0ebfe20e6c64914ea2dcecdbac9 (diff)
parent714e11d53534416b6519396a9df5d62054731810 (diff)
downloademacs-574d33b4737cf0829eb85c802710bfc42093f6d1.tar.gz
Merge remote-tracking branch 'origin/master' into athena/unstable
-rw-r--r--INSTALL27
-rw-r--r--configure.ac35
-rw-r--r--doc/emacs/frames.texi14
-rw-r--r--doc/emacs/maintaining.texi27
-rw-r--r--doc/emacs/search.texi16
-rw-r--r--doc/lispref/frames.texi6
-rw-r--r--doc/lispref/functions.texi9
-rw-r--r--doc/misc/gnus.texi3
-rw-r--r--etc/NEWS27
-rw-r--r--lisp/battery.el2
-rw-r--r--lisp/emacs-lisp/easy-mmode.el6
-rw-r--r--lisp/emacs-lisp/inline.el2
-rw-r--r--lisp/emacs-lisp/macroexp.el8
-rw-r--r--lisp/emacs-lisp/pp.el5
-rw-r--r--lisp/emacs-lisp/shortdoc.el3
-rw-r--r--lisp/ffap.el11
-rw-r--r--lisp/frame.el80
-rw-r--r--lisp/gnus/gnus-sum.el7
-rw-r--r--lisp/gnus/nnimap.el2
-rw-r--r--lisp/gnus/nntp.el8
-rw-r--r--lisp/hi-lock.el21
-rw-r--r--lisp/image-dired.el4
-rw-r--r--lisp/indent.el35
-rw-r--r--lisp/international/emoji.el75
-rw-r--r--lisp/ldefs-boot.el203
-rw-r--r--lisp/man.el26
-rw-r--r--lisp/menu-bar.el7
-rw-r--r--lisp/mouse.el6
-rw-r--r--lisp/net/dictionary.el2
-rw-r--r--lisp/net/mailcap.el79
-rw-r--r--lisp/org/ob-gnuplot.el25
-rw-r--r--lisp/org/org-agenda.el5
-rw-r--r--lisp/org/org-version.el2
-rw-r--r--lisp/org/org.el20
-rw-r--r--lisp/org/ox-ascii.el6
-rw-r--r--lisp/outline.el178
-rw-r--r--lisp/paren.el4
-rw-r--r--lisp/progmodes/gud.el11
-rw-r--r--lisp/progmodes/python.el12
-rw-r--r--lisp/progmodes/xref.el45
-rw-r--r--lisp/simple.el3
-rw-r--r--lisp/subr.el14
-rw-r--r--lisp/term/x-win.el18
-rw-r--r--lisp/vc/pcvs-info.el8
-rw-r--r--src/buffer.c2
-rw-r--r--src/data.c16
-rw-r--r--src/emacsgtkfixed.c6
-rw-r--r--src/frame.c2
-rw-r--r--src/gtkutil.c5
-rw-r--r--src/haiku_draw_support.cc2
-rw-r--r--src/haiku_support.cc10
-rw-r--r--src/haikuterm.c55
-rw-r--r--src/pgtkterm.c22
-rw-r--r--src/xdisp.c3
-rw-r--r--src/xfaces.c8
-rw-r--r--src/xfns.c6
-rw-r--r--src/xsettings.h5
-rw-r--r--src/xterm.c112
-rw-r--r--src/xwidget.c2
-rw-r--r--test/lisp/emacs-lisp/edebug-tests.el10
-rw-r--r--test/lisp/ffap-tests.el17
-rw-r--r--test/lisp/net/mailcap-resources/mailcap9
-rw-r--r--test/lisp/net/mailcap-resources/test.test1
-rw-r--r--test/lisp/net/mailcap-tests.el70
-rw-r--r--test/lisp/so-long-tests/spelling-tests.el17
65 files changed, 1085 insertions, 402 deletions
diff --git a/INSTALL b/INSTALL
index 02d5a09d63c..7cb7e0526a2 100644
--- a/INSTALL
+++ b/INSTALL
@@ -226,6 +226,33 @@ e.g. 'emacs25'). On Red Hat-based systems, the corresponding command is
On FreeBSD, the command is 'pkg install -y `pkg rquery %dn emacs-devel`'.
+* Alternative window systems
+
+If you want to use Emacs on one of the alternative window systems
+available on GNU/Linux and some Unix systems, such as Wayland or
+Broadway, you can build the PGTK ("Pure GTK") port of Emacs, which
+utilizes the GTK+ toolkit to support those window systems. To this
+end, invoke the configure script with the '--with-pgtk' option, like
+this:
+
+ ./configure --with-pgtk
+
+This build is only supported with GTK+ version 3, and it is an error
+to specify any other X-specific configuration option when PGTK is
+enabled.
+
+With the PGTK build, you will be able to switch between running Emacs
+on X, Wayland and Broadway using the 'GDK_BACKEND' environment
+variable. GTK+ should automatically detect and use the correct value
+for your system, but you can also specify it manually. For example,
+to force GTK+ to run under Broadway, start Emacs like this:
+
+ GDK_BACKEND=broadway emacs ...
+
+(where '...' denotes any further options you may want to pass to Emacs).
+
+The GNUstep build also supports the Wayland window system. If that is
+what you want, see nextstep/INSTALL.
DETAILED BUILDING AND INSTALLATION:
diff --git a/configure.ac b/configure.ac
index baf8c8018ec..955f0918fd4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3409,41 +3409,6 @@ if test "${with_xim}" != "no"; then
[Define to 1 to default runtime use of XIM to on.])
fi
-
-if test "${HAVE_XIM}" != "no"; then
- late_CFLAGS=$CFLAGS
- if test "$GCC" = yes; then
- CFLAGS="$CFLAGS --pedantic-errors"
- fi
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
-#include <X11/Xlib.h>
-#include <X11/Xresource.h>]],
-[[Display *display;
-XrmDatabase db;
-char *res_name;
-char *res_class;
-XIDProc *callback;
-XPointer *client_data;
-#ifndef __GNUC__
-/* If we're not using GCC, it's probably not XFree86, and this is
- probably right, but we can't use something like --pedantic-errors. */
-extern Bool XRegisterIMInstantiateCallback(Display*, XrmDatabase, char*,
- char*, XIMProc, XPointer*);
-#endif
-(void)XRegisterIMInstantiateCallback(display, db, res_name, res_class, callback,
- client_data);]])],
- [emacs_cv_arg6_star=yes])
- AH_TEMPLATE(XRegisterIMInstantiateCallback_arg6,
- [Define to the type of the 6th arg of XRegisterIMInstantiateCallback,
-either XPointer or XPointer*.])dnl
- if test "$emacs_cv_arg6_star" = yes; then
- AC_DEFINE(XRegisterIMInstantiateCallback_arg6, [XPointer*])
- else
- AC_DEFINE(XRegisterIMInstantiateCallback_arg6, [XPointer])
- fi
- CFLAGS=$late_CFLAGS
-fi
-
# Check for XRender
HAVE_XRENDER=no
if test "${HAVE_X11}" = "yes"; then
diff --git a/doc/emacs/frames.texi b/doc/emacs/frames.texi
index c641b8ccb14..ba58f70caf3 100644
--- a/doc/emacs/frames.texi
+++ b/doc/emacs/frames.texi
@@ -515,12 +515,14 @@ error if there is only one frame.
@item C-x 5 u
@kindex C-x 5 u
@findex undelete-frame
-@findex undelete-frame-mode
-When @code{undelete-frame-mode} is enabled, undelete one of the 16
-most recently deleted frames. Without a prefix argument, undelete the
-most recently deleted frame. With a numerical prefix argument between
-1 and 16, where 1 is the most recently deleted frame, undelete the
-corresponding deleted frame.
+@findex undelete-frame-max
+Undelete one of the recently deleted frames. The user option
+@code{undelete-frame-max} specifies the maximum number of deleted
+frames to keep (the default is 1). Without a prefix argument,
+undelete the most recently deleted frame. With a numerical prefix
+argument between 1 and the number specified by @code{undelete-frame-max},
+where 1 is the most recently deleted frame, undelete the corresponding
+deleted frame.
@item C-z
@kindex C-z @r{(X windows)}
diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi
index 9a23f23e0ed..edcc6075f75 100644
--- a/doc/emacs/maintaining.texi
+++ b/doc/emacs/maintaining.texi
@@ -2317,10 +2317,15 @@ them.
@item M-?
Find all the references for the identifier at point.
-@item M-x xref-query-replace-in-results @key{RET} @var{regexp} @key{RET} @var{replacement} @key{RET}
+@item M-x xref-query-replace-in-results @key{RET} @var{replacement} @key{RET}
+@itemx C-u M-x xref-query-replace-in-results @key{RET} @var{regexp} @key{RET} @var{replacement} @key{RET}
Interactively replace @var{regexp} with @var{replacement} in the names
of all the identifiers shown in the @file{*xref*} buffer.
+@item M-x xref-find-references-and-replace @key{RET} @var{from} @key{RET} @var{to} @key{RET}
+Interactively rename all instances of the identifier @var{from} to the
+new name @var{to}.
+
@item M-x tags-search @key{RET} @var{regexp} @key{RET}
Search for @var{regexp} through the files in the selected tags
table.
@@ -2358,13 +2363,21 @@ shown. The default value is @code{nil}, which just shows the results
in the @file{*xref*} buffer, but doesn't select any of them.
@findex xref-query-replace-in-results
- @kbd{M-x xref-query-replace-in-results} reads a regexp to match identifier
-names and a replacement string, just like ordinary @kbd{M-x
-query-replace-regexp}. It then performs the specified replacement in
-the names of the matching identifiers in all the places in all the
-files where these identifiers are referenced. This is useful when you
+ @kbd{M-x xref-query-replace-in-results} reads a @var{replacement}
+string, just like ordinary @kbd{M-x query-replace-regexp}. It then
+renames the identifiers shown in the @file{*xref*} buffer in all the
+places in all the files where these identifiers are referenced, such
+that their new name is @var{replacement}. This is useful when you
rename your identifiers as part of refactoring. This command should
-be invoked in the @file{*xref*} buffer generated by @kbd{M-?}.
+be invoked in the @file{*xref*} buffer generated by @kbd{M-?}. With a
+prefix argument, the command also prompts for a regexp to match
+identifier names, and renames that regexp in the names of the matching
+identifiers with @var{replacement}.
+
+@findex xref-find-references-and-replace
+ @kbd{M-x xref-find-references-and-replace} works similarly to
+@code{xref-query-replace-in-results}, but is more convenient when you
+want to rename a single identifier specified by its name @var{from}.
@findex tags-search
@kbd{M-x tags-search} reads a regexp using the minibuffer, then
diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index 397bddbe995..a57cfac8daf 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -436,14 +436,6 @@ incremental search adds the @samp{control-S} character to the search
string.
@item
-@findex isearch-char-by-name
-@kindex C-x 8 RET @r{(Incremental Search)}
-Type @kbd{C-x 8 @key{RET}} (@code{isearch-char-by-name}), followed by
-a Unicode name or code-point in hex. This adds the specified
-character into the search string, similar to the usual
-@code{insert-char} command (@pxref{Inserting Text}).
-
-@item
@kindex C-^ @r{(Incremental Search)}
@findex isearch-toggle-input-method
@findex isearch-toggle-specified-input-method
@@ -471,6 +463,14 @@ transient input method (@pxref{transient input method}) with
@kbd{C-x \} (@code{isearch-transient-input-method}) to insert a single
character to the search string using an input method, and
automatically disable the input method afterwards.
+
+@item
+@findex isearch-char-by-name
+@kindex C-x 8 RET @r{(Incremental Search)}
+Type @kbd{C-x 8 @key{RET}} (@code{isearch-char-by-name}), followed by
+a Unicode name or code-point in hex. This adds the specified
+character into the search string, similar to the usual
+@code{insert-char} command (@pxref{Inserting Text}).
@end itemize
@findex isearch-emoji-by-name
diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index ca7d9ada0ba..2eeb8b7ed74 100644
--- a/doc/lispref/frames.texi
+++ b/doc/lispref/frames.texi
@@ -3154,10 +3154,8 @@ raises @var{frame} above all other child frames of its parent.
@deffn Command lower-frame &optional frame
This function lowers frame @var{frame} (default, the selected frame)
below all other frames belonging to the same or a higher z-group as
-@var{frame}.@footnote{Lowering frames is not supported on Haiku, due
-to limitations imposed by the system.} If @var{frame} is a child
-frame (@pxref{Child Frames}), this lowers @var{frame} below all other
-child frames of its parent.
+@var{frame}. If @var{frame} is a child frame (@pxref{Child Frames}),
+this lowers @var{frame} below all other child frames of its parent.
@end deffn
@defun frame-restack frame1 frame2 &optional above
diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi
index f2dce71e96c..2378e9efd7e 100644
--- a/doc/lispref/functions.texi
+++ b/doc/lispref/functions.texi
@@ -670,11 +670,10 @@ records. @xref{Function Cells}.
@end defun
@defun function-alias-p object &optional noerror
-Use the @code{function-alias-p} function to check whether an object is
-a function alias. If it isn't, this predicate will return
-@code{nil}. If it is, the value returned will be a list of symbol
-representing the function alias chain. For instance, if @code{a} is
-an alias for @code{b}, and @code{b} is an alias for @code{c}:
+Checks whether @var{object} is a function alias. If it is, it returns
+a list of symbols representing the function alias chain, else
+@code{nil}. For instance, if @code{a} is an alias for @code{b}, and
+@code{b} is an alias for @code{c}:
@example
(function-alias-p 'a)
diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi
index 61870311ed8..b3efdfbacba 100644
--- a/doc/misc/gnus.texi
+++ b/doc/misc/gnus.texi
@@ -12223,7 +12223,6 @@ controlling variable is a predicate list, as described above.
@vindex gnus-treat-highlight-citation
@vindex gnus-treat-highlight-headers
@vindex gnus-treat-highlight-signature
-@vindex gnus-treat-play-sounds
@vindex gnus-treat-x-pgp-sig
@vindex gnus-treat-unfold-headers
@vindex gnus-treat-fold-headers
@@ -12359,8 +12358,6 @@ is controlled by @code{gnus-body-boundary-delimiter}.
@xref{Article Highlighting}.
-@vindex gnus-treat-play-sounds
-@item gnus-treat-play-sounds
@item gnus-treat-ansi-sequences (t)
@vindex gnus-treat-x-pgp-sig
@item gnus-treat-x-pgp-sig (head)
diff --git a/etc/NEWS b/etc/NEWS
index 06a6886ebf6..fdbfd9b1bea 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -243,6 +243,16 @@ These will take you (respectively) to the next and previous "page".
---
*** 'describe-char' now also outputs the name of emoji combinations.
+** Outline Mode
+
+*** Support for a default visibility state.
+Customize the option 'outline-default-state' to define what headings
+are visible when the mode is set. When equal to a number, the option
+'outline-default-rules' determines the visibility of the subtree
+starting at the corresponding level. Values are provided to show
+a heading subtree unless the heading match a regexp, or its subtree
+has long lines or is long.
+
** Outline Minor Mode
+++
@@ -277,11 +287,12 @@ height use 'window-height' in combination with 'body-lines'.
+++
*** Deleted frames can now be undeleted.
-The 16 most recently deleted frames can be undeleted with 'C-x 5 u' when
-'undelete-frame-mode' is enabled. Without a prefix argument, undelete
-the most recently deleted frame. With a numerical prefix argument
-between 1 and 16, where 1 is the most recently deleted frame, undelete
-the corresponding deleted frame.
+The most recently deleted frame can be undeleted with 'C-x 5 u' when
+the new user option 'undelete-frame-max' has its default value 1.
+Without a prefix argument, undelete the most recently deleted frame.
+With a numerical prefix argument between 1 and 'undelete-frame-max',
+where 1 is the most recently deleted frame, undelete the corresponding
+deleted frame.
** Tab Bars and Tab Lines
@@ -594,6 +605,12 @@ to enable the display of the buffer list.
It is bound to 'C-M-,' and jumps to the location where 'xref-go-back'
('M-,', also known as 'xref-pop-marker-stack') was invoked previously.
+*** 'xref-query-replace-in-results' does not prompt for FROM when
+called without prefix argument, to make the most common case faster:
+replacing entire matches.
+
+*** New command 'xref-find-references-and-replace' to rename one identifier.
+
** File notifications
+++
diff --git a/lisp/battery.el b/lisp/battery.el
index 45334163fa6..b7b81a11a1c 100644
--- a/lisp/battery.el
+++ b/lisp/battery.el
@@ -96,12 +96,14 @@ Value does not include \".\" or \"..\"."
(cond ((member battery-upower-service (dbus-list-activatable-names))
#'battery-upower)
((and (eq system-type 'gnu/linux)
+ (file-readable-p "/sys/")
(battery--find-linux-sysfs-batteries))
#'battery-linux-sysfs)
((and (eq system-type 'gnu/linux)
(file-directory-p "/proc/acpi/battery"))
#'battery-linux-proc-acpi)
((and (eq system-type 'gnu/linux)
+ (file-readable-p "/proc/")
(file-readable-p "/proc/apm"))
#'battery-linux-proc-apm)
((and (eq system-type 'berkeley-unix)
diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el
index cf3ea8c3ddf..688c76e0c54 100644
--- a/lisp/emacs-lisp/easy-mmode.el
+++ b/lisp/emacs-lisp/easy-mmode.el
@@ -696,7 +696,11 @@ Valid keywords and arguments are:
(defmacro easy-mmode-defmap (m bs doc &rest args)
"Define a constant M whose value is the result of `easy-mmode-define-keymap'.
The M, BS, and ARGS arguments are as per that function. DOC is
-the constant's documentation."
+the constant's documentation.
+
+This macro is deprecated; use `defvar-keymap' instead."
+ ;; FIXME: Declare obsolete in favor of `defvar-keymap'. It is still
+ ;; used for `gud-menu-map' and `gud-minor-mode-map', so fix that first.
(declare (doc-string 3) (indent 1))
`(defconst ,m
(easy-mmode-define-keymap ,bs nil (if (boundp ',m) ,m) ,(cons 'list args))
diff --git a/lisp/emacs-lisp/inline.el b/lisp/emacs-lisp/inline.el
index 963e117ff34..de0112db631 100644
--- a/lisp/emacs-lisp/inline.el
+++ b/lisp/emacs-lisp/inline.el
@@ -71,7 +71,7 @@
(defmacro inline-quote (_exp)
"Similar to backquote, but quotes code and only accepts , and not ,@."
- (declare (debug backquote-form))
+ (declare (debug (backquote-form)))
(error "inline-quote can only be used within define-inline"))
(defmacro inline-const-p (_exp)
diff --git a/lisp/emacs-lisp/macroexp.el b/lisp/emacs-lisp/macroexp.el
index b44917f7d56..33ce55a3de8 100644
--- a/lisp/emacs-lisp/macroexp.el
+++ b/lisp/emacs-lisp/macroexp.el
@@ -366,14 +366,18 @@ Assumes the caller has bound `macroexpand-all-environment'."
form)
(macroexp--expand-all newform))))
- (`(funcall . ,(or `(,exp . ,args) pcase--dontcare))
+ (`(funcall ,exp . ,args)
(let ((eexp (macroexp--expand-all exp))
(eargs (macroexp--all-forms args)))
;; Rewrite (funcall #'foo bar) to (foo bar), in case `foo'
;; has a compiler-macro, or to unfold it.
(pcase eexp
- (`#',f (macroexp--expand-all `(,f . ,eargs)))
+ ((and `#',f
+ (guard (not (or (special-form-p f) (macrop f)))));; bug#46636
+ (macroexp--expand-all `(,f . ,eargs)))
(_ `(funcall ,eexp . ,eargs)))))
+ (`(funcall . ,_) form) ;bug#53227
+
(`(,func . ,_)
(let ((handler (function-get func 'compiler-macro))
(funargs (function-get func 'funarg-positions)))
diff --git a/lisp/emacs-lisp/pp.el b/lisp/emacs-lisp/pp.el
index d199716b2c5..e782cdb1dab 100644
--- a/lisp/emacs-lisp/pp.el
+++ b/lisp/emacs-lisp/pp.el
@@ -273,7 +273,10 @@ Use the `pp-max-width' variable to control the desired line length."
(insert "(")
(pp--insert start (pop sexp))
(while sexp
- (pp--insert " " (pop sexp)))
+ (if (consp sexp)
+ (pp--insert " " (pop sexp))
+ (pp--insert " . " sexp)
+ (setq sexp nil)))
(insert ")")))
(defun pp--format-function (sexp)
diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el
index 870d34527b0..658edd67527 100644
--- a/lisp/emacs-lisp/shortdoc.el
+++ b/lisp/emacs-lisp/shortdoc.el
@@ -1299,6 +1299,9 @@ If FUNCTION is non-nil, place point on the entry for FUNCTION (if any)."
(text-property-search-forward 'shortdoc-function function t)
(beginning-of-line)))
+;;;###autoload
+(defalias 'shortdoc #'shortdoc-display-group)
+
(defun shortdoc--display-function (data)
(let ((function (pop data))
(start-section (point))
diff --git a/lisp/ffap.el b/lisp/ffap.el
index f9220817a71..b5d2a02cd1d 100644
--- a/lisp/ffap.el
+++ b/lisp/ffap.el
@@ -1449,10 +1449,13 @@ which may actually result in an URL rather than a filename."
(ffap-file-exists-string (substring name 0 (match-beginning 0)))))
;; If it contains a colon, get rid of it (and return if exists)
((and (string-match path-separator name)
- (setq name (ffap-string-at-point 'nocolon))
- (> (length name) 0)
- (ffap-file-exists-string name)))
- ;; File does not exist, try the alist:
+ (let ((this-name (ffap-string-at-point 'nocolon)))
+ ;; But don't interpret the first part if ":/bin" as
+ ;; the empty string.
+ (when (> (length this-name) 0)
+ (setq name this-name)
+ (ffap-file-exists-string name)))))
+ ;; File does not exist, try the alist:
((let ((alist ffap-alist) tem try case-fold-search)
(while (and alist (not try))
(setq tem (car alist) alist (cdr alist))
diff --git a/lisp/frame.el b/lisp/frame.el
index 599ffe591a5..5926a4d748b 100644
--- a/lisp/frame.el
+++ b/lisp/frame.el
@@ -2529,6 +2529,13 @@ deleting them."
(if iconify (iconify-frame this) (delete-frame this)))
(setq this next))))
+
+(defcustom undelete-frame-max 1
+ "Maximum number of deleted frames before oldest are thrown away."
+ :type 'integer
+ :group 'frames
+ :version "29.1")
+
(eval-when-compile (require 'frameset))
(defvar undelete-frame--deleted-frames nil
@@ -2536,7 +2543,7 @@ deleting them."
(defun undelete-frame--handle-delete-frame (frame)
"Save the configuration of frames deleted with `delete-frame'.
-Only the 16 most recently deleted frames are saved."
+Only the `undelete-frame-max' most recently deleted frames are saved."
(when (frame-live-p frame)
(setq undelete-frame--deleted-frames
(cons
@@ -2555,54 +2562,45 @@ Only the 16 most recently deleted frames are saved."
(cons '(display . :never)
frameset-filter-alist))))
undelete-frame--deleted-frames))
- (if (> (length undelete-frame--deleted-frames) 16)
+ (if (> (length undelete-frame--deleted-frames) undelete-frame-max)
(setq undelete-frame--deleted-frames
(butlast undelete-frame--deleted-frames)))))
-(define-minor-mode undelete-frame-mode
- "Enable the `undelete-frame' command."
- :group 'frames
- :global t
- (if undelete-frame-mode
- (add-hook 'delete-frame-functions
- #'undelete-frame--handle-delete-frame -75)
- (remove-hook 'delete-frame-functions
- #'undelete-frame--handle-delete-frame)
- (setq undelete-frame--deleted-frames nil)))
+(add-hook 'after-init-hook
+ (lambda ()
+ (add-hook 'delete-frame-functions
+ #'undelete-frame--handle-delete-frame -75)))
(defun undelete-frame (&optional arg)
"Undelete a frame deleted with `delete-frame'.
-Without a prefix argument, undelete the most recently deleted
-frame.
-With a numerical prefix argument ARG between 1 and 16, where 1 is
-most recently deleted frame, undelete the ARGth deleted frame.
+Without a prefix argument, undelete the most recently deleted frame.
+With a numerical prefix argument ARG between 1 and `undelete-frame-max',
+where 1 is most recently deleted frame, undelete the ARGth deleted frame.
When called from Lisp, returns the new frame."
(interactive "P")
- (if (not undelete-frame-mode)
- (user-error "Undelete-Frame mode is disabled")
- (if (consp arg)
- (user-error "Missing deleted frame number argument")
- (let* ((number (pcase arg ('nil 1) ('- -1) (_ arg)))
- (frames (frame-list))
- (frameset (nth (1- number) undelete-frame--deleted-frames))
- (graphic (display-graphic-p)))
- (if (not (<= 1 number 16))
- (user-error "%d is not a valid deleted frame number argument"
- number)
- (if (not frameset)
- (user-error "No deleted frame with number %d" number)
- (if (not (eq graphic (car frameset)))
- (user-error
- "Cannot undelete a %s display frame on a %s display"
- (if graphic "non-graphic" "graphic")
- (if graphic "graphic" "non-graphic"))
- (setq undelete-frame--deleted-frames
- (delq frameset undelete-frame--deleted-frames))
- (frameset-restore (cdr frameset))
- (let ((frame (car (seq-difference (frame-list) frames))))
- (when frame
- (select-frame-set-input-focus frame)
- frame)))))))))
+ (if (consp arg)
+ (user-error "Missing deleted frame number argument")
+ (let* ((number (pcase arg ('nil 1) ('- -1) (_ arg)))
+ (frames (frame-list))
+ (frameset (nth (1- number) undelete-frame--deleted-frames))
+ (graphic (display-graphic-p)))
+ (if (not (<= 1 number undelete-frame-max))
+ (user-error "%d is not a valid deleted frame number argument"
+ number)
+ (if (not frameset)
+ (user-error "No deleted frame with number %d" number)
+ (if (not (eq graphic (car frameset)))
+ (user-error
+ "Cannot undelete a %s display frame on a %s display"
+ (if graphic "non-graphic" "graphic")
+ (if graphic "graphic" "non-graphic"))
+ (setq undelete-frame--deleted-frames
+ (delq frameset undelete-frame--deleted-frames))
+ (frameset-restore (cdr frameset))
+ (let ((frame (car (seq-difference (frame-list) frames))))
+ (when frame
+ (select-frame-set-input-focus frame)
+ frame))))))))
;;; Window dividers.
(defgroup window-divider nil
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index d3e476b5d64..6dfdcaf55c7 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -11898,7 +11898,8 @@ Returns nil if no threads were there to be hidden."
(beginning-of-line)
(let ((start (point))
(starteol (line-end-position))
- (article (gnus-summary-article-number)))
+ (article (unless (gnus-summary-article-intangible-p)
+ (gnus-summary-article-number))))
;; Go forward until either the buffer ends or the subthread ends.
(when (and (not (eobp))
(or (zerop (gnus-summary-next-thread 1 t))
@@ -11912,7 +11913,9 @@ Returns nil if no threads were there to be hidden."
(let ((ol (make-overlay starteol (point) nil t nil)))
(overlay-put ol 'invisible 'gnus-sum)
(overlay-put ol 'evaporate t)))
- (gnus-summary-goto-subject article)
+ (if article
+ (gnus-summary-goto-subject article)
+ (gnus-summary-position-point))
;; We moved backward past the start point (invisible thread?)
(when (> start (point))
(goto-char starteol)))
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index 090cb9b245b..cff628061e9 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -246,7 +246,7 @@ during splitting, which may be slow."
(nnimap-header-parameters))
t)
(unless (process-live-p (get-buffer-process (current-buffer)))
- (error "Server closed connection"))
+ (error "IMAP server %S closed connection" nnimap-address))
(nnimap-transform-headers)
(nnheader-remove-cr-followed-by-lf))
(insert-buffer-substring
diff --git a/lisp/gnus/nntp.el b/lisp/gnus/nntp.el
index 624c64d4d75..0dcff9743ad 100644
--- a/lisp/gnus/nntp.el
+++ b/lisp/gnus/nntp.el
@@ -306,7 +306,7 @@ backend doesn't catch this error.")
(nntp-record-command string))
(process-send-string process (concat string nntp-end-of-line))
(or (memq (process-status process) '(open run))
- (nntp-report "Server closed connection")))
+ (nntp-report "NNTP server %S closed connection" nntp-address)))
(defun nntp-record-command (string)
"Record the command STRING."
@@ -369,7 +369,7 @@ retried once before actually displaying the error report."
(nntp-snarf-error-message)
nil))
((not (memq (process-status process) '(open run)))
- (nntp-report "Server closed connection"))
+ (nntp-report "NNTP server %S closed connection" nntp-address))
(t
(goto-char (point-max))
(let ((limit (point-min))
@@ -1431,7 +1431,7 @@ If SEND-IF-FORCE, only send authinfo to the server if the
;; be the process's former output buffer (i.e. now killed)
(or (and process
(memq (process-status process) '(open run)))
- (nntp-report "Server closed connection")))))
+ (nntp-report "NNTP server %S closed connection" nntp-address)))))
(defun nntp-accept-response ()
"Wait for output from the process that outputs to BUFFER."
@@ -1450,7 +1450,7 @@ If SEND-IF-FORCE, only send authinfo to the server if the
(when group
(let ((entry (nntp-find-connection-entry nntp-server-buffer)))
(cond ((not entry)
- (nntp-report "Server closed connection"))
+ (nntp-report "NNTP server %S closed connection" nntp-address))
((not (equal group (caddr entry)))
(with-current-buffer (process-buffer (car entry))
(erase-buffer)
diff --git a/lisp/hi-lock.el b/lisp/hi-lock.el
index fbd698e234a..b77f9181a9c 100644
--- a/lisp/hi-lock.el
+++ b/lisp/hi-lock.el
@@ -854,6 +854,27 @@ SPACES-REGEXP is a regexp to substitute spaces in font-lock search."
;; continue standard unloading
nil)
+;;; Mouse support
+(defalias 'highlight-symbol-at-mouse 'hi-lock-face-symbol-at-mouse)
+(defun hi-lock-face-symbol-at-mouse (event)
+ "Highlight symbol at mouse click EVENT."
+ (interactive "e")
+ (save-excursion
+ (mouse-set-point event)
+ (highlight-symbol-at-point)))
+
+;;;###autoload
+(defun hi-lock-context-menu (menu click)
+ "Populate MENU with a menu item to highlight symbol at CLICK."
+ (when (thing-at-mouse click 'symbol)
+ (define-key-after menu [highlight-search-separator] menu-bar-separator
+ 'middle-separator)
+ (define-key-after menu [highlight-search-mouse]
+ '(menu-item "Highlight Symbol" highlight-symbol-at-mouse
+ :help "Highlight symbol at point")
+ 'highlight-search-separator))
+ menu)
+
(provide 'hi-lock)
;;; hi-lock.el ends here
diff --git a/lisp/image-dired.el b/lisp/image-dired.el
index 536f29441ae..b81df8567bd 100644
--- a/lisp/image-dired.el
+++ b/lisp/image-dired.el
@@ -609,9 +609,7 @@ See also `image-dired-thumbnail-storage'."
((eq 'use-image-dired-dir image-dired-thumbnail-storage)
(let* ((f (expand-file-name file))
(hash
- ;; SHA1 is slightly faster than MD5, so let's use it.
- ;; (We don't need anything crytographically strong.)
- (sha1 (file-name-as-directory (file-name-directory f)))))
+ (md5 (file-name-as-directory (file-name-directory f)))))
(format "%s%s%s.thumb.%s"
(file-name-as-directory (expand-file-name (image-dired-dir)))
(file-name-base f)
diff --git a/lisp/indent.el b/lisp/indent.el
index 40669b38424..d20c8053c5f 100644
--- a/lisp/indent.el
+++ b/lisp/indent.el
@@ -77,10 +77,11 @@ This variable has no effect unless `tab-always-indent' is `complete'."
:group 'indent
:type '(choice
(const :tag "Always complete" nil)
- (const :tag "Unless at the end of a line" 'eol)
- (const :tag "Unless looking at a word" 'word)
- (const :tag "Unless at a word or parenthesis" 'word-or-paren)
- (const :tag "Unless at a word, parenthesis, or punctuation." 'word-or-paren-or-punct))
+ (const :tag "Unless at the end of a line" eol)
+ (const :tag "Unless looking at a word" word)
+ (const :tag "Unless at a word or parenthesis" word-or-paren)
+ (const :tag "Unless at a word, parenthesis, or punctuation."
+ word-or-paren-or-punct))
:version "28.1")
(defvar indent-line-ignored-functions '(indent-relative
@@ -170,7 +171,7 @@ prefix argument is ignored."
(let ((old-tick (buffer-chars-modified-tick))
(old-point (point))
(old-indent (current-indentation))
- (syn `(,(syntax-after (point)))))
+ (syn (syntax-after (point))))
;; Indent the line.
(or (not (eq (indent--funcall-widened indent-line-function) 'noindent))
@@ -182,21 +183,21 @@ prefix argument is ignored."
(cond
;; If the text was already indented right, try completion.
((and (eq tab-always-indent 'complete)
- (eq old-point (point))
- (eq old-tick (buffer-chars-modified-tick))
+ (eql old-point (point))
+ (eql old-tick (buffer-chars-modified-tick))
(or (null tab-first-completion)
(eq last-command this-command)
- (and (equal tab-first-completion 'eol)
+ (and (eq tab-first-completion 'eol)
(eolp))
- (and (member tab-first-completion
- '(word word-or-paren word-or-paren-or-punct))
- (not (member 2 syn)))
- (and (member tab-first-completion
- '(word-or-paren word-or-paren-or-punct))
- (not (or (member 4 syn)
- (member 5 syn))))
- (and (equal tab-first-completion 'word-or-paren-or-punct)
- (not (member 1 syn)))))
+ (and (memq tab-first-completion
+ '(word word-or-paren word-or-paren-or-punct))
+ (not (eql 2 syn)))
+ (and (memq tab-first-completion
+ '(word-or-paren word-or-paren-or-punct))
+ (not (or (eql 4 syn)
+ (eql 5 syn))))
+ (and (eq tab-first-completion 'word-or-paren-or-punct)
+ (not (eql 1 syn)))))
(completion-at-point))
;; If a prefix argument was given, rigidly indent the following
diff --git a/lisp/international/emoji.el b/lisp/international/emoji.el
index 264a1f09dc2..df488708afa 100644
--- a/lisp/international/emoji.el
+++ b/lisp/international/emoji.el
@@ -55,6 +55,14 @@
"Face for emojis that have derivations."
:version "29.1")
+(defvar emoji-alternate-names nil
+ "Alist of emojis and lists of alternate names for the emojis.
+Each element in the alist should have the emoji (as a string) as
+the first element, and the rest of the elements should be strings
+representing names. For instance:
+
+ (\"🤗\" \"hug\" \"hugging\" \"kind\")")
+
(defvar emoji--labels nil)
(defvar emoji--all-bases nil)
(defvar emoji--derived nil)
@@ -90,8 +98,9 @@ of selecting from emoji display."
;;;###autoload
(defun emoji-search ()
"Choose and insert an emoji glyph by typing its Unicode name.
-This command prompts for an emoji name, with completion, and inserts it.
-It recognizes the Unicode Standard names of emoji."
+This command prompts for an emoji name, with completion, and
+inserts it. It recognizes the Unicode Standard names of emoji,
+and also consults the `emoji-alternate-names' alist."
(interactive "*")
(emoji--init)
(emoji--choose-emoji))
@@ -647,29 +656,47 @@ We prefer the earliest unique letter."
(defun emoji--choose-emoji ()
;; Use the list of names.
- (let ((name
- (completing-read
- "Insert emoji: "
- (lambda (string pred action)
- (if (eq action 'metadata)
- (list 'metadata
- (cons
- 'affixation-function
- ;; Add the glyphs to the start of the displayed
- ;; strings when TAB-ing.
- (lambda (strings)
- (mapcar
- (lambda (name)
- (list name
- (concat
- (or (gethash name emoji--all-bases) " ")
- "\t")
- ""))
- strings))))
- (complete-with-action action emoji--all-bases string pred)))
- nil t)))
+ (let* ((table
+ (if (not emoji-alternate-names)
+ ;; If we don't have alternate names, do the efficient version.
+ emoji--all-bases
+ ;; Compute all the (possibly non-unique) names.
+ (let ((table nil))
+ (maphash
+ (lambda (name glyph)
+ (push (concat name "\t" glyph) table))
+ emoji--all-bases)
+ (dolist (elem emoji-alternate-names)
+ (dolist (name (cdr elem))
+ (push (concat name "\t" (car elem)) table)))
+ (sort table #'string<))))
+ (name
+ (completing-read
+ "Insert emoji: "
+ (lambda (string pred action)
+ (if (eq action 'metadata)
+ (list 'metadata
+ (cons
+ 'affixation-function
+ ;; Add the glyphs to the start of the displayed
+ ;; strings when TAB-ing.
+ (lambda (strings)
+ (mapcar
+ (lambda (name)
+ (if emoji-alternate-names
+ (list name "" "")
+ (list name
+ (concat
+ (or (gethash name emoji--all-bases) " ")
+ "\t")
+ "")))
+ strings))))
+ (complete-with-action action table string pred)))
+ nil t)))
(when (cl-plusp (length name))
- (let* ((glyph (gethash name emoji--all-bases))
+ (let* ((glyph (if emoji-alternate-names
+ (cadr (split-string name "\t"))
+ (gethash name emoji--all-bases)))
(derived (gethash glyph emoji--derived)))
(if (not derived)
;; Simple glyph with no derivations.
diff --git a/lisp/ldefs-boot.el b/lisp/ldefs-boot.el
index 6d5b0d84e6b..05d461e41e9 100644
--- a/lisp/ldefs-boot.el
+++ b/lisp/ldefs-boot.el
@@ -8861,8 +8861,12 @@ Define a constant M whose value is the result of `easy-mmode-define-keymap'.
The M, BS, and ARGS arguments are as per that function. DOC is
the constant's documentation.
+This macro is deprecated; use `defvar-keymap' instead.
+
\(fn M BS DOC &rest ARGS)" nil t)
+(function-put 'easy-mmode-defmap 'doc-string-elt '3)
+
(function-put 'easy-mmode-defmap 'lisp-indent-function '1)
(autoload 'easy-mmode-defsyntax "easy-mmode" "\
@@ -8871,6 +8875,8 @@ CSS contains a list of syntax specifications of the form (CHAR . SYNTAX).
\(fn ST CSS DOC &rest ARGS)" nil t)
+(function-put 'easy-mmode-defsyntax 'doc-string-elt '3)
+
(function-put 'easy-mmode-defsyntax 'lisp-indent-function '1)
(register-definition-prefixes "easy-mmode" '("easy-mmode-"))
@@ -10291,6 +10297,31 @@ disabled.
;;;### (autoloads nil "elide-head" "elide-head.el" (0 0 0 0))
;;; Generated autoloads from elide-head.el
+(autoload 'elide-head-mode "elide-head" "\
+Toggle eliding (hiding) header material in the current buffer.
+
+This is a minor mode. If called interactively, toggle the `Elide-Head
+mode' mode. If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable the
+mode if ARG is nil, omitted, or is a positive number. Disable the
+mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `elide-head-mode'.
+
+The mode's hook is called both when the mode is enabled and when it is
+disabled.
+
+When Elide Header mode is enabled, headers are hidden according
+to `elide-head-headers-to-hide'.
+
+This is suitable as an entry on `find-file-hook' or appropriate
+mode hooks.
+
+\(fn &optional ARG)" t nil)
+
(autoload 'elide-head "elide-head" "\
Hide header material in buffer according to `elide-head-headers-to-hide'.
@@ -10301,6 +10332,8 @@ This is suitable as an entry on `find-file-hook' or appropriate mode hooks.
\(fn &optional ARG)" t nil)
+(make-obsolete 'elide-head 'elide-head-mode '"29.1")
+
(register-definition-prefixes "elide-head" '("elide-head-"))
;;;***
@@ -16764,6 +16797,11 @@ be found in variable `hi-lock-interactive-patterns'." t nil)
(autoload 'hi-lock-find-patterns "hi-lock" "\
Add patterns from the current buffer to the list of hi-lock patterns." t nil)
+(autoload 'hi-lock-context-menu "hi-lock" "\
+Populate MENU with a menu item to highlight symbol at CLICK.
+
+\(fn MENU CLICK)" nil nil)
+
(register-definition-prefixes "hi-lock" '("hi-lock-" "turn-on-hi-lock-if-enabled"))
;;;***
@@ -19155,25 +19193,37 @@ system." t nil)
(put 'info-lookup-symbol 'info-file "emacs")
(autoload 'info-lookup-symbol "info-look" "\
-Display the definition of SYMBOL, as found in the relevant manual.
-When this command is called interactively, it reads SYMBOL from the
-minibuffer. In the minibuffer, use \\<minibuffer-local-completion-map>\\[next-history-element] to yank the default argument
-value into the minibuffer so you can edit it. The default symbol is the
-one found at point.
+Look up and display documentation of SYMBOL in the relevant Info manual.
+SYMBOL should be an identifier: a function or method, a macro, a variable,
+a data type, a class, etc.
-With prefix arg MODE a query for the symbol help mode is offered.
+Interactively, prompt for SYMBOL; you can use \\<minibuffer-local-completion-map>\\[next-history-element] in the minibuffer
+to yank the default argument value into the minibuffer so you can edit it.
+The default symbol is the one found at point.
+
+MODE is the major mode whose Info manuals to search for the documentation
+of SYMBOL. It defaults to the current buffer's `major-mode'; if that
+mode doesn't have any Info manuals known to Emacs, the command will
+prompt for MODE to use, with completion. With prefix arg, the command
+always prompts for MODE.
\(fn SYMBOL &optional MODE)" t nil)
(put 'info-lookup-file 'info-file "emacs")
(autoload 'info-lookup-file "info-look" "\
-Display the documentation of a file.
-When this command is called interactively, it reads FILE from the minibuffer.
-In the minibuffer, use \\<minibuffer-local-completion-map>\\[next-history-element] to yank the default file name
-into the minibuffer so you can edit it.
+Look up and display documentation of FILE in the relevant Info manual.
+FILE should be the name of a file; a notable example is a standard header
+file that is part of the C or C++ standard library.
+
+Interactively, prompt for FILE; you can use \\<minibuffer-local-completion-map>\\[next-history-element] in the minibuffer
+to yank the default argument value into the minibuffer so you can edit it.
The default file name is the one found at point.
-With prefix arg MODE a query for the file help mode is offered.
+MODE is the major mode whose Info manuals to search for the documentation
+of FILE. It defaults to the current buffer's `major-mode'; if that
+mode doesn't have any Info manuals known to Emacs, the command will
+prompt for MODE to use, with completion. With prefix arg, the command
+always prompts for MODE.
\(fn FILE &optional MODE)" t nil)
@@ -19859,7 +19909,7 @@ one of the aforementioned options instead of using this mode.
;;;### (autoloads nil "jsonrpc" "jsonrpc.el" (0 0 0 0))
;;; Generated autoloads from jsonrpc.el
-(push (purecopy '(jsonrpc 1 0 14)) package--builtin-versions)
+(push (purecopy '(jsonrpc 1 0 15)) package--builtin-versions)
(register-definition-prefixes "jsonrpc" '("jsonrpc-"))
@@ -21311,6 +21361,11 @@ Default bookmark handler for Man buffers.
\(fn BOOKMARK)" nil nil)
+(autoload 'Man-context-menu "man" "\
+Populate MENU with commands that open a man page at point.
+
+\(fn MENU CLICK)" nil nil)
+
(register-definition-prefixes "man" '("Man-" "man"))
;;;***
@@ -31067,6 +31122,8 @@ If FUNCTION is non-nil, place point on the entry for FUNCTION (if any).
\(fn GROUP &optional FUNCTION)" t nil)
+(defalias 'shortdoc #'shortdoc-display-group)
+
(register-definition-prefixes "shortdoc" '("alist" "buffer" "define-short-documentation-group" "file" "hash-table" "keymaps" "list" "number" "overlay" "process" "regexp" "sequence" "shortdoc-" "string" "text-properties" "vector"))
;;;***
@@ -39394,6 +39451,32 @@ unless `windmove-create-window' is non-nil and a new window is created.
\(fn &optional ARG)" t nil)
+(defvar windmove-mode t "\
+Non-nil if Windmove mode is enabled.
+See the `windmove-mode' command
+for a description of this minor mode.")
+
+(custom-autoload 'windmove-mode "windmove" nil)
+
+(autoload 'windmove-mode "windmove" "\
+Global minor mode for default windmove commands.
+
+This is a minor mode. If called interactively, toggle the `Windmove
+mode' mode. If the prefix argument is positive, enable the mode, and
+if it is zero or negative, disable the mode.
+
+If called from Lisp, toggle the mode if ARG is `toggle'. Enable the
+mode if ARG is nil, omitted, or is a positive number. Disable the
+mode if ARG is a negative number.
+
+To check whether the minor mode is enabled in the current buffer,
+evaluate `(default-value \\='windmove-mode)'.
+
+The mode's hook is called both when the mode is enabled and when it is
+disabled.
+
+\(fn &optional ARG)" t nil)
+
(autoload 'windmove-default-keybindings "windmove" "\
Set up keybindings for `windmove'.
Keybindings are of the form MODIFIERS-{left,right,up,down},
@@ -39969,24 +40052,23 @@ Zone out, completely." t nil)
;;;### (autoloads nil nil ("abbrev.el" "bindings.el" "buff-menu.el"
;;;;;; "button.el" "calc/calc-aent.el" "calc/calc-embed.el" "calc/calc-misc.el"
-;;;;;; "calc/calc-yank.el" "case-table.el" "cedet/ede/base.el" "cedet/ede/config.el"
-;;;;;; "cedet/ede/cpp-root.el" "cedet/ede/custom.el" "cedet/ede/dired.el"
-;;;;;; "cedet/ede/emacs.el" "cedet/ede/files.el" "cedet/ede/generic.el"
-;;;;;; "cedet/ede/linux.el" "cedet/ede/locate.el" "cedet/ede/make.el"
-;;;;;; "cedet/ede/shell.el" "cedet/ede/speedbar.el" "cedet/ede/system.el"
-;;;;;; "cedet/ede/util.el" "cedet/semantic/analyze.el" "cedet/semantic/analyze/complete.el"
-;;;;;; "cedet/semantic/analyze/refs.el" "cedet/semantic/bovine.el"
-;;;;;; "cedet/semantic/bovine/c-by.el" "cedet/semantic/bovine/c.el"
-;;;;;; "cedet/semantic/bovine/el.el" "cedet/semantic/bovine/gcc.el"
-;;;;;; "cedet/semantic/bovine/make-by.el" "cedet/semantic/bovine/make.el"
-;;;;;; "cedet/semantic/bovine/scm-by.el" "cedet/semantic/bovine/scm.el"
-;;;;;; "cedet/semantic/complete.el" "cedet/semantic/ctxt.el" "cedet/semantic/db-file.el"
-;;;;;; "cedet/semantic/db-find.el" "cedet/semantic/db-global.el"
-;;;;;; "cedet/semantic/db-mode.el" "cedet/semantic/db-typecache.el"
-;;;;;; "cedet/semantic/db.el" "cedet/semantic/debug.el" "cedet/semantic/decorate/include.el"
-;;;;;; "cedet/semantic/decorate/mode.el" "cedet/semantic/dep.el"
-;;;;;; "cedet/semantic/doc.el" "cedet/semantic/edit.el" "cedet/semantic/find.el"
-;;;;;; "cedet/semantic/format.el" "cedet/semantic/grammar-wy.el"
+;;;;;; "calc/calc-yank.el" "case-table.el" "cedet/ede/cpp-root.el"
+;;;;;; "cedet/ede/custom.el" "cedet/ede/dired.el" "cedet/ede/emacs.el"
+;;;;;; "cedet/ede/files.el" "cedet/ede/generic.el" "cedet/ede/linux.el"
+;;;;;; "cedet/ede/locate.el" "cedet/ede/make.el" "cedet/ede/speedbar.el"
+;;;;;; "cedet/ede/system.el" "cedet/ede/util.el" "cedet/semantic/analyze.el"
+;;;;;; "cedet/semantic/analyze/complete.el" "cedet/semantic/analyze/refs.el"
+;;;;;; "cedet/semantic/bovine.el" "cedet/semantic/bovine/c-by.el"
+;;;;;; "cedet/semantic/bovine/c.el" "cedet/semantic/bovine/el.el"
+;;;;;; "cedet/semantic/bovine/gcc.el" "cedet/semantic/bovine/make-by.el"
+;;;;;; "cedet/semantic/bovine/make.el" "cedet/semantic/bovine/scm-by.el"
+;;;;;; "cedet/semantic/bovine/scm.el" "cedet/semantic/complete.el"
+;;;;;; "cedet/semantic/ctxt.el" "cedet/semantic/db-file.el" "cedet/semantic/db-find.el"
+;;;;;; "cedet/semantic/db-global.el" "cedet/semantic/db-mode.el"
+;;;;;; "cedet/semantic/db-typecache.el" "cedet/semantic/db.el" "cedet/semantic/debug.el"
+;;;;;; "cedet/semantic/decorate/include.el" "cedet/semantic/decorate/mode.el"
+;;;;;; "cedet/semantic/dep.el" "cedet/semantic/doc.el" "cedet/semantic/edit.el"
+;;;;;; "cedet/semantic/find.el" "cedet/semantic/format.el" "cedet/semantic/grammar-wy.el"
;;;;;; "cedet/semantic/grm-wy-boot.el" "cedet/semantic/html.el"
;;;;;; "cedet/semantic/ia-sb.el" "cedet/semantic/ia.el" "cedet/semantic/idle.el"
;;;;;; "cedet/semantic/imenu.el" "cedet/semantic/lex-spp.el" "cedet/semantic/lex.el"
@@ -40005,8 +40087,8 @@ Zone out, completely." t nil)
;;;;;; "cedet/srecode/insert.el" "cedet/srecode/java.el" "cedet/srecode/map.el"
;;;;;; "cedet/srecode/mode.el" "cedet/srecode/srt-wy.el" "cedet/srecode/srt.el"
;;;;;; "cedet/srecode/template.el" "cedet/srecode/texi.el" "composite.el"
-;;;;;; "cus-face.el" "cus-start.el" "custom.el" "dired-aux.el" "dired-x.el"
-;;;;;; "electric.el" "emacs-lisp/backquote.el" "emacs-lisp/byte-run.el"
+;;;;;; "cus-face.el" "cus-load.el" "cus-start.el" "custom.el" "dired-aux.el"
+;;;;;; "dired-x.el" "electric.el" "emacs-lisp/backquote.el" "emacs-lisp/byte-run.el"
;;;;;; "emacs-lisp/cl-extra.el" "emacs-lisp/cl-macs.el" "emacs-lisp/cl-preloaded.el"
;;;;;; "emacs-lisp/cl-seq.el" "emacs-lisp/easymenu.el" "emacs-lisp/eieio-custom.el"
;;;;;; "emacs-lisp/eieio-opt.el" "emacs-lisp/float-sup.el" "emacs-lisp/lisp-mode.el"
@@ -40028,30 +40110,41 @@ Zone out, completely." t nil)
;;;;;; "eshell/em-pred.el" "eshell/em-prompt.el" "eshell/em-rebind.el"
;;;;;; "eshell/em-script.el" "eshell/em-smart.el" "eshell/em-term.el"
;;;;;; "eshell/em-tramp.el" "eshell/em-unix.el" "eshell/em-xtra.el"
-;;;;;; "faces.el" "files.el" "font-core.el" "font-lock.el" "format.el"
-;;;;;; "frame.el" "help.el" "hfy-cmap.el" "ibuf-ext.el" "indent.el"
-;;;;;; "international/characters.el" "international/charscript.el"
-;;;;;; "international/cp51932.el" "international/emoji-zwj.el" "international/eucjp-ms.el"
+;;;;;; "eshell/esh-groups.el" "faces.el" "files.el" "finder-inf.el"
+;;;;;; "font-core.el" "font-lock.el" "format.el" "frame.el" "help.el"
+;;;;;; "hfy-cmap.el" "ibuf-ext.el" "indent.el" "international/characters.el"
+;;;;;; "international/charprop.el" "international/charscript.el"
+;;;;;; "international/cp51932.el" "international/emoji-labels.el"
+;;;;;; "international/emoji-zwj.el" "international/eucjp-ms.el"
;;;;;; "international/iso-transl.el" "international/mule-cmds.el"
-;;;;;; "international/mule-conf.el" "international/mule.el" "isearch.el"
-;;;;;; "jit-lock.el" "jka-cmpr-hook.el" "keymap.el" "language/burmese.el"
-;;;;;; "language/cham.el" "language/chinese.el" "language/cyrillic.el"
-;;;;;; "language/czech.el" "language/english.el" "language/ethiopic.el"
-;;;;;; "language/european.el" "language/georgian.el" "language/greek.el"
-;;;;;; "language/hebrew.el" "language/indian.el" "language/japanese.el"
-;;;;;; "language/khmer.el" "language/korean.el" "language/lao.el"
-;;;;;; "language/misc-lang.el" "language/romanian.el" "language/sinhala.el"
-;;;;;; "language/slovak.el" "language/tai-viet.el" "language/thai.el"
-;;;;;; "language/tibetan.el" "language/utf-8-lang.el" "language/vietnamese.el"
-;;;;;; "ldefs-boot.el" "leim/ja-dic/ja-dic.el" "leim/leim-list.el"
-;;;;;; "leim/quail/4Corner.el" "leim/quail/ARRAY30.el" "leim/quail/CCDOSPY.el"
-;;;;;; "leim/quail/CTLau-b5.el" "leim/quail/CTLau.el" "leim/quail/ECDICT.el"
-;;;;;; "leim/quail/ETZY.el" "leim/quail/PY-b5.el" "leim/quail/PY.el"
-;;;;;; "leim/quail/Punct-b5.el" "leim/quail/Punct.el" "leim/quail/QJ-b5.el"
-;;;;;; "leim/quail/QJ.el" "leim/quail/SW.el" "leim/quail/TONEPY.el"
-;;;;;; "leim/quail/ZIRANMA.el" "leim/quail/ZOZY.el" "leim/quail/arabic.el"
-;;;;;; "leim/quail/cham.el" "leim/quail/compose.el" "leim/quail/croatian.el"
-;;;;;; "leim/quail/cyril-jis.el" "leim/quail/cyrillic.el" "leim/quail/czech.el"
+;;;;;; "international/mule-conf.el" "international/mule.el" "international/uni-bidi.el"
+;;;;;; "international/uni-brackets.el" "international/uni-category.el"
+;;;;;; "international/uni-combining.el" "international/uni-comment.el"
+;;;;;; "international/uni-decimal.el" "international/uni-decomposition.el"
+;;;;;; "international/uni-digit.el" "international/uni-lowercase.el"
+;;;;;; "international/uni-mirrored.el" "international/uni-name.el"
+;;;;;; "international/uni-numeric.el" "international/uni-old-name.el"
+;;;;;; "international/uni-special-lowercase.el" "international/uni-special-titlecase.el"
+;;;;;; "international/uni-special-uppercase.el" "international/uni-titlecase.el"
+;;;;;; "international/uni-uppercase.el" "isearch.el" "jit-lock.el"
+;;;;;; "jka-cmpr-hook.el" "keymap.el" "language/burmese.el" "language/cham.el"
+;;;;;; "language/chinese.el" "language/cyrillic.el" "language/czech.el"
+;;;;;; "language/english.el" "language/ethiopic.el" "language/european.el"
+;;;;;; "language/georgian.el" "language/greek.el" "language/hebrew.el"
+;;;;;; "language/indian.el" "language/japanese.el" "language/khmer.el"
+;;;;;; "language/korean.el" "language/lao.el" "language/misc-lang.el"
+;;;;;; "language/romanian.el" "language/sinhala.el" "language/slovak.el"
+;;;;;; "language/tai-viet.el" "language/thai.el" "language/tibetan.el"
+;;;;;; "language/utf-8-lang.el" "language/vietnamese.el" "ldefs-boot.el"
+;;;;;; "leim/ja-dic/ja-dic.el" "leim/leim-list.el" "leim/quail/4Corner.el"
+;;;;;; "leim/quail/ARRAY30.el" "leim/quail/CCDOSPY.el" "leim/quail/CTLau-b5.el"
+;;;;;; "leim/quail/CTLau.el" "leim/quail/ECDICT.el" "leim/quail/ETZY.el"
+;;;;;; "leim/quail/PY-b5.el" "leim/quail/PY.el" "leim/quail/Punct-b5.el"
+;;;;;; "leim/quail/Punct.el" "leim/quail/QJ-b5.el" "leim/quail/QJ.el"
+;;;;;; "leim/quail/SW.el" "leim/quail/TONEPY.el" "leim/quail/ZIRANMA.el"
+;;;;;; "leim/quail/ZOZY.el" "leim/quail/arabic.el" "leim/quail/cham.el"
+;;;;;; "leim/quail/compose.el" "leim/quail/croatian.el" "leim/quail/cyril-jis.el"
+;;;;;; "leim/quail/cyrillic.el" "leim/quail/czech.el" "leim/quail/emoji.el"
;;;;;; "leim/quail/georgian.el" "leim/quail/greek.el" "leim/quail/hanja-jis.el"
;;;;;; "leim/quail/hanja.el" "leim/quail/hanja3.el" "leim/quail/hebrew.el"
;;;;;; "leim/quail/ipa-praat.el" "leim/quail/latin-alt.el" "leim/quail/latin-ltx.el"
diff --git a/lisp/man.el b/lisp/man.el
index adf244a11ad..a53a696c313 100644
--- a/lisp/man.el
+++ b/lisp/man.el
@@ -1976,6 +1976,32 @@ Uses `Man-name-local-regexp'."
(bookmark-default-handler
`("" (buffer . ,buf) . ,(bookmark-get-bookmark-record bookmark)))))
+;;; Mouse support
+(defun Man-at-mouse (e)
+ "Open man manual at point."
+ (interactive "e")
+ (save-excursion
+ (mouse-set-point e)
+ (man (Man-default-man-entry))))
+
+;;;###autoload
+(defun Man-context-menu (menu click)
+ "Populate MENU with commands that open a man page at point."
+ (save-excursion
+ (mouse-set-point click)
+ (when (save-excursion
+ (skip-syntax-backward "^ ")
+ (and (looking-at
+ "[[:space:]]*\\([[:alnum:]_-]+([[:alnum:]]+)\\)")
+ (match-string 1)))
+ (define-key-after menu [man-separator] menu-bar-separator
+ 'middle-separator)
+ (define-key-after menu [man-at-mouse]
+ '(menu-item "Open man page" Man-at-mouse
+ :help "Open man page around mouse click")
+ 'man-separator)))
+ menu)
+
;; Init the man package variables, if not already done.
(Man-init-defvars)
diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el
index 36cbd6a9c51..e5a070b24ad 100644
--- a/lisp/menu-bar.el
+++ b/lisp/menu-bar.el
@@ -109,14 +109,9 @@
(bindings--define-key menu [separator-tab]
menu-bar-separator))
- (bindings--define-key menu [enable-undelete-frame-mode]
- '(menu-item "Enable Undeleting Frames" undelete-frame-mode
- :visible (null undelete-frame-mode)
- :help "Enable undeleting frames in this session"))
(bindings--define-key menu [undelete-last-deleted-frame]
'(menu-item "Undelete Frame" undelete-frame
- :visible (and undelete-frame-mode
- (car undelete-frame--deleted-frames))
+ :visible (car undelete-frame--deleted-frames)
:help "Undelete the most recently deleted frame"))
;; Don't use delete-frame as event name because that is a special
diff --git a/lisp/mouse.el b/lisp/mouse.el
index 1a76b9a0b66..502683d3d1e 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -298,6 +298,10 @@ and should return the same menu with changes such as added new menu items."
(function-item context-menu-buffers)
(function-item context-menu-vc)
(function-item context-menu-ffap)
+ (function-item hi-lock-context-menu)
+ (function-item occur-context-menu)
+ (function-item Man-context-menu)
+ (function-item dictionary-context-menu)
(function :tag "Custom function")))
:version "28.1")
@@ -320,6 +324,8 @@ the function `context-menu-filter-function'."
(fun (mouse-posn-property (event-start click)
'context-menu-function)))
+ (select-window (posn-window (event-start click)))
+
(if (functionp fun)
(setq menu (funcall fun menu click))
(run-hook-wrapped 'context-menu-functions
diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el
index 507363cc0f8..e0824f39716 100644
--- a/lisp/net/dictionary.el
+++ b/lisp/net/dictionary.el
@@ -1376,7 +1376,7 @@ any buffer where (dictionary-tooltip-mode 1) has been called."
(dictionary-search word)))
;;;###autoload
-(defun context-menu-dictionary (menu click)
+(defun dictionary-context-menu (menu click)
"Populate MENU with dictionary commands at CLICK.
When you add this function to `context-menu-functions',
the context menu will contain an item that searches
diff --git a/lisp/net/mailcap.el b/lisp/net/mailcap.el
index bf3c8edd1e3..b65f7c25b83 100644
--- a/lisp/net/mailcap.el
+++ b/lisp/net/mailcap.el
@@ -319,8 +319,9 @@ attribute name (viewer, test, etc). This looks like:
Where VIEWERINFO specifies how the content-type is viewed. Can be
a string, in which case it is run through a shell, with appropriate
-parameters, or a symbol, in which case the symbol is `funcall'ed if
-and only if it exists as a function, with the buffer as an argument.
+parameters, or a symbol, in which case the symbol must name a function
+of zero arguments which is called in a buffer holding the MIME part's
+content.
TESTINFO is a test for the viewer's applicability, or nil. If nil, it
means the viewer is always valid. If it is a Lisp function, it is
@@ -439,9 +440,10 @@ MAILCAPS if set; otherwise (on Unix) use the path from RFC 1524, plus
("/usr/local/etc/mailcap" system)))))
(when (stringp path)
(setq path (mapcar #'list (split-string path path-separator t))))
- (when (seq-some (lambda (f)
- (file-has-changed-p (car f) 'mail-parse-mailcaps))
- path)
+ (when (or (null mailcap--computed-mime-data)
+ (seq-some (lambda (f)
+ (file-has-changed-p (car f) 'mail-parse-mailcaps))
+ path))
;; Clear out all old data.
(setq mailcap--computed-mime-data nil)
;; Add the Emacs-distributed defaults (which will be used as
@@ -1174,34 +1176,45 @@ See \"~/.mailcap\", `mailcap-mime-data' and related files and variables."
(mailcap-parse-mailcaps)
(let ((command (mailcap-mime-info
(mailcap-extension-to-mime (file-name-extension file)))))
- (unless command
- (error "No viewer for %s" (file-name-extension file)))
- ;; Remove quotes around the file name - we'll use shell-quote-argument.
- (while (string-match "['\"]%s['\"]" command)
- (setq command (replace-match "%s" t t command)))
- (setq command (replace-regexp-in-string
- "%s"
- (shell-quote-argument (convert-standard-filename file))
- command
- nil t))
- ;; Handlers such as "gio open" and kde-open5 start viewer in background
- ;; and exit immediately. Avoid `start-process' since it assumes
- ;; :connection-type `pty' and kills children processes with SIGHUP
- ;; when temporary terminal session is finished (Bug#44824).
- ;; An alternative is `process-connection-type' let-bound to nil for
- ;; `start-process-shell-command' call (with no chance to report failure).
- (make-process
- :name "mailcap-view-file"
- :connection-type 'pipe
- :buffer nil ; "*Messages*" may be suitable for debugging
- :sentinel (lambda (proc event)
- (when (and (memq (process-status proc) '(exit signal))
- (/= (process-exit-status proc) 0))
- (message
- "Command %s: %s."
- (mapconcat #'identity (process-command proc) " ")
- (substring event 0 -1))))
- :command (list shell-file-name shell-command-switch command))))
+ (if (functionp command)
+ ;; command is a viewer function (a mode) expecting the file
+ ;; contents to be in the current buffer.
+ (let ((buf (generate-new-buffer (file-name-nondirectory file))))
+ (set-buffer buf)
+ (insert-file-contents file)
+ (setq buffer-file-name file)
+ (funcall command)
+ (set-buffer-modified-p nil)
+ (pop-to-buffer buf))
+ ;; command is a program to run with file as an argument.
+ (unless command
+ (error "No viewer for %s" (file-name-extension file)))
+ ;; Remove quotes around the file name - we'll use shell-quote-argument.
+ (while (string-match "['\"]%s['\"]" command)
+ (setq command (replace-match "%s" t t command)))
+ (setq command (replace-regexp-in-string
+ "%s"
+ (shell-quote-argument (convert-standard-filename file))
+ command
+ nil t))
+ ;; Handlers such as "gio open" and kde-open5 start viewer in background
+ ;; and exit immediately. Avoid `start-process' since it assumes
+ ;; :connection-type `pty' and kills children processes with SIGHUP
+ ;; when temporary terminal session is finished (Bug#44824).
+ ;; An alternative is `process-connection-type' let-bound to nil for
+ ;; `start-process-shell-command' call (with no chance to report failure).
+ (make-process
+ :name "mailcap-view-file"
+ :connection-type 'pipe
+ :buffer nil ; "*Messages*" may be suitable for debugging
+ :sentinel (lambda (proc event)
+ (when (and (memq (process-status proc) '(exit signal))
+ (/= (process-exit-status proc) 0))
+ (message
+ "Command %s: %s."
+ (mapconcat #'identity (process-command proc) " ")
+ (substring event 0 -1))))
+ :command (list shell-file-name shell-command-switch command)))))
(provide 'mailcap)
diff --git a/lisp/org/ob-gnuplot.el b/lisp/org/ob-gnuplot.el
index 69a5f5f91bd..895738822de 100644
--- a/lisp/org/ob-gnuplot.el
+++ b/lisp/org/ob-gnuplot.el
@@ -129,6 +129,7 @@ code."
(title (cdr (assq :title params)))
(lines (cdr (assq :line params)))
(sets (cdr (assq :set params)))
+ (missing (cdr (assq :missing params)))
(x-labels (cdr (assq :xlabels params)))
(y-labels (cdr (assq :ylabels params)))
(timefmt (cdr (assq :timefmt params)))
@@ -138,6 +139,7 @@ code."
(file-name-directory (buffer-file-name))))
(add-to-body (lambda (text) (setq body (concat text "\n" body)))))
;; append header argument settings to body
+ (when missing (funcall add-to-body (format "set datafile missing '%s'" missing)))
(when title (funcall add-to-body (format "set title '%s'" title)))
(when lines (mapc (lambda (el) (funcall add-to-body el)) lines))
(when sets
@@ -288,21 +290,14 @@ Pass PARAMS through to `orgtbl-to-generic' when exporting TABLE."
(with-temp-file data-file
(insert (let ((org-babel-gnuplot-timestamp-fmt
(or (plist-get params :timefmt) "%Y-%m-%d-%H:%M:%S")))
- (replace-regexp-in-string
- ;; org export backend adds "|" at the beginning/end of
- ;; the table lines. Strip those.
- "^|\\(.+\\)|$"
- "\\1"
- (orgtbl-to-generic
- table
- (org-combine-plists
- '( :sep "\t" :fmt org-babel-gnuplot-quote-tsv-field
- ;; Two setting below are needed to make :fmt work.
- :raw t
- ;; Use `org', not `ascii' because `ascii' may
- ;; sometimes mishandle quoted strings.
- :backend org)
- params))))))
+ (orgtbl-to-generic
+ table
+ (org-combine-plists
+ '( :sep "\t" :fmt org-babel-gnuplot-quote-tsv-field
+ ;; Two setting below are needed to make :fmt work.
+ :raw t
+ :backend ascii)
+ params)))))
data-file)
(provide 'ob-gnuplot)
diff --git a/lisp/org/org-agenda.el b/lisp/org/org-agenda.el
index fed36ac9b63..94aea1b0a32 100644
--- a/lisp/org/org-agenda.el
+++ b/lisp/org/org-agenda.el
@@ -86,6 +86,8 @@
(declare-function org-capture "org-capture" (&optional goto keys))
(declare-function org-clock-modify-effort-estimate "org-clock" (&optional value))
+(declare-function org-element-type "org-element" (&optional element))
+
(defvar calendar-mode-map)
(defvar org-clock-current-task)
(defvar org-current-tag-alist)
@@ -5729,7 +5731,8 @@ displayed in agenda view."
(org-at-planning-p)
(org-before-first-heading-p)
(and org-agenda-include-inactive-timestamps
- (org-at-clock-log-p)))
+ (org-at-clock-log-p))
+ (not (eq 'timestamp (org-element-type (org-element-context)))))
(throw :skip nil))
(org-agenda-skip))
(let* ((pos (match-beginning 0))
diff --git a/lisp/org/org-version.el b/lisp/org/org-version.el
index 1053bbe22cc..5337d9df746 100644
--- a/lisp/org/org-version.el
+++ b/lisp/org/org-version.el
@@ -11,7 +11,7 @@ Inserted by installing Org mode or when a release is made."
(defun org-git-version ()
"The Git version of Org mode.
Inserted by installing Org or when a release is made."
- (let ((org-git-version "release_9.5.2-3-geb9f34"))
+ (let ((org-git-version "release_9.5.2-9-g7ba24c"))
org-git-version))
(provide 'org-version)
diff --git a/lisp/org/org.el b/lisp/org/org.el
index fba45caabe6..f5d4df3d9c6 100644
--- a/lisp/org/org.el
+++ b/lisp/org/org.el
@@ -18731,17 +18731,19 @@ With prefix arg UNCOMPILED, load the uncompiled versions."
"Is S an ID created by UUIDGEN?"
(string-match "\\`[0-9a-f]\\{8\\}-[0-9a-f]\\{4\\}-[0-9a-f]\\{4\\}-[0-9a-f]\\{4\\}-[0-9a-f]\\{12\\}\\'" (downcase s)))
-(defun org-in-src-block-p (&optional inside)
+(defun org-in-src-block-p (&optional inside element)
"Whether point is in a code source block.
When INSIDE is non-nil, don't consider we are within a source
-block when point is at #+BEGIN_SRC or #+END_SRC."
- (let ((case-fold-search t))
- (or (and (eq (get-char-property (point) 'src-block) t))
- (and (not inside)
- (save-match-data
- (save-excursion
- (beginning-of-line)
- (looking-at ".*#\\+\\(begin\\|end\\)_src")))))))
+block when point is at #+BEGIN_SRC or #+END_SRC.
+When ELEMENT is provided, it is considered to be element at point."
+ (save-match-data (setq element (or element (org-element-at-point))))
+ (when (eq 'src-block (org-element-type element))
+ (or (not inside)
+ (not (or (= (line-beginning-position)
+ (org-element-property :post-affiliated element))
+ (= (1+ (line-end-position))
+ (- (org-element-property :end element)
+ (org-element-property :post-blank element))))))))
(defun org-context ()
"Return a list of contexts of the current cursor position.
diff --git a/lisp/org/ox-ascii.el b/lisp/org/ox-ascii.el
index c22bb13b6dd..38b2a5772c1 100644
--- a/lisp/org/ox-ascii.el
+++ b/lisp/org/ox-ascii.el
@@ -1929,7 +1929,11 @@ a communication channel."
(org-export-table-cell-alignment table-cell info)))))
(setq contents
(concat data
- (make-string (- width (string-width (or data ""))) ?\s))))
+ ;; FIXME: If CONTENTS was transformed by filters,
+ ;; the whole width calculation can be wrong.
+ ;; At least, make sure that we do not throw error
+ ;; when CONTENTS is larger than width.
+ (make-string (max 0 (- width (string-width (or data "")))) ?\s))))
;; Return cell.
(concat (format " %s " contents)
(when (memq 'right (org-export-table-cell-borders table-cell info))
diff --git a/lisp/outline.el b/lisp/outline.el
index 4027142c94e..8e4af64370b 100644
--- a/lisp/outline.el
+++ b/lisp/outline.el
@@ -351,7 +351,8 @@ Turning on outline mode calls the value of `text-mode-hook' and then of
'(outline-font-lock-keywords t nil nil backward-paragraph))
(setq-local imenu-generic-expression
(list (list nil (concat "^\\(?:" outline-regexp "\\).*$") 0)))
- (add-hook 'change-major-mode-hook #'outline-show-all nil t))
+ (add-hook 'change-major-mode-hook #'outline-show-all nil t)
+ (add-hook 'hack-local-variables-hook #'outline-apply-default-state nil t))
(defvar outline-minor-mode-map)
@@ -434,7 +435,8 @@ See the command `outline-mode' for more information on this mode."
nil t)
(setq-local line-move-ignore-invisible t)
;; Cause use of ellipses for invisible text.
- (add-to-invisibility-spec '(outline . t)))
+ (add-to-invisibility-spec '(outline . t))
+ (outline-apply-default-state))
(when outline-minor-mode-highlight
(if font-lock-fontified
(font-lock-remove-keywords nil outline-font-lock-keywords))
@@ -1303,6 +1305,178 @@ convenient way to make a table of contents of the buffer."
(insert "\n\n"))))))
(kill-new (buffer-string)))))))
+(defcustom outline-default-state nil
+ "If non-nil, some headings are initially outlined.
+
+Note that the default state is applied when the major mode is set
+or when the command `outline-apply-default-state' is called
+interactively.
+
+When nil, headings visibility is left unchanged.
+
+If equal to `outline-show-all', all text of buffer is shown.
+
+If equal to `outline-show-only-headings', only headings are shown.
+
+If equal to a number, show only headings up to and including the
+corresponding level. See `outline-default-rules' to customize
+visibility of the subtree at the choosen level.
+
+If equal to a lambda function or function name, this function is
+expected to toggle headings visibility, and will be called after
+the mode is enabled."
+ :version "29.1"
+ :type '(choice (const :tag "Disabled" nil)
+ (const :tag "Show all" outline-show-all)
+ (const :tag "Only headings" outline-show-only-headings)
+ (natnum :tag "Show headings up to level" :value 1)
+ (function :tag "Custom function")))
+
+(defcustom outline-default-rules nil
+ "Determines visibility of subtree starting at `outline-default-state' level.
+
+When nil, the subtree is hidden unconditionally.
+
+When equal to a list, each element should be one of the following:
+
+- A cons cell with CAR `match-regexp' and CDR a regexp, the
+ subtree will be hidden when the outline heading match the
+ regexp.
+
+- `subtree-has-long-lines' to only show the heading branches when
+ long lines are detected in its subtree (see
+ `outline-default-long-line' for the definition of long lines).
+
+- `subtree-is-long' to only show the heading branches when its
+ subtree contains more than `outline-default-line-count' lines.
+
+- A lambda function or function name which will be evaluated with
+ point at the beginning of the heading and the match data set
+ appropriately, the function being expected to toggle the
+ heading visibility."
+ :version "29.1"
+ :type '(choice (const :tag "Hide subtree" nil)
+ (set :tag "Show subtree unless"
+ (cons :tag "Heading match regexp"
+ (const match-regexp) string)
+ (const :tag "Subtree has long lines"
+ subtree-has-long-lines)
+ (const :tag "Subtree is long"
+ subtree-is-long)
+ (cons :tag "Custom function"
+ (const custom-function) function))))
+
+(defcustom outline-default-long-line 1000
+ "Minimal number of characters in a line for a heading to be outlined."
+ :version "29.1"
+ :type '(natnum :tag "Number of characters"))
+
+(defcustom outline-default-line-count 50
+ "Minimal number of lines for a heading to be outlined."
+ :version "29.1"
+ :type '(natnum :tag "Number of lines"))
+
+(defun outline-apply-default-state ()
+ "Apply the outline state defined by `outline-default-state'."
+ (interactive)
+ (cond
+ ((integerp outline-default-state)
+ (outline--show-headings-up-to-level outline-default-state))
+ ((functionp outline-default-state)
+ (funcall outline-default-state))))
+
+(defun outline-show-only-headings ()
+ "Show only headings."
+ (interactive)
+ (outline-show-all)
+ (outline-hide-region-body (point-min) (point-max)))
+
+(eval-when-compile (require 'so-long))
+(autoload 'so-long-detected-long-line-p "so-long")
+(defvar so-long-skip-leading-comments)
+(defvar so-long-threshold)
+(defvar so-long-max-lines)
+
+(defun outline--show-headings-up-to-level (level)
+ "Show only headings up to a LEVEL level.
+
+Like `outline-hide-sublevels' but, for each heading at level
+LEVEL, decides of subtree visibility according to
+`outline-default-rules'."
+ (if (not outline-default-rules)
+ (outline-hide-sublevels level)
+ (if (< level 1)
+ (error "Must keep at least one level of headers"))
+ (save-excursion
+ (let* (outline-view-change-hook
+ (beg (progn
+ (goto-char (point-min))
+ ;; Skip the prelude, if any.
+ (unless (outline-on-heading-p t) (outline-next-heading))
+ (point)))
+ (end (progn
+ (goto-char (point-max))
+ ;; Keep empty last line, if available.
+ (if (bolp) (1- (point)) (point))))
+ (heading-regexp
+ (cdr-safe
+ (assoc 'match-regexp outline-default-rules)))
+ (check-line-count
+ (memq 'subtree-is-long outline-default-rules))
+ (check-long-lines
+ (memq 'subtree-has-long-lines outline-default-rules))
+ (custom-function
+ (cdr-safe
+ (assoc 'custom-function outline-default-rules))))
+ (if (< end beg)
+ (setq beg (prog1 end (setq end beg))))
+ ;; First hide everything.
+ (outline-hide-sublevels level)
+ ;; Then unhide the top level headers.
+ (outline-map-region
+ (lambda ()
+ (let ((current-level (funcall outline-level)))
+ (when (< current-level level)
+ (outline-show-heading)
+ (outline-show-entry))
+ (when (= current-level level)
+ (cond
+ ((and heading-regexp
+ (let ((beg (point))
+ (end (progn (outline-end-of-heading) (point))))
+ (string-match-p heading-regexp (buffer-substring beg end))))
+ ;; hide entry when heading match regexp
+ (outline-hide-entry))
+ ((and check-line-count
+ (save-excursion
+ (let ((beg (point))
+ (end (progn (outline-end-of-subtree) (point))))
+ (<= outline-default-line-count (count-lines beg end)))))
+ ;; show only branches when line count of subtree >
+ ;; threshold
+ (outline-show-branches))
+ ((and check-long-lines
+ (save-excursion
+ (let ((beg (point))
+ (end (progn (outline-end-of-subtree) (point))))
+ (save-restriction
+ (narrow-to-region beg end)
+ (let ((so-long-skip-leading-comments nil)
+ (so-long-threshold outline-default-long-line)
+ (so-long-max-lines nil))
+ (so-long-detected-long-line-p))))))
+ ;; show only branches when long lines are detected
+ ;; in subtree
+ (outline-show-branches))
+ (custom-function
+ ;; call custom function if defined
+ (funcall custom-function))
+ (t
+ ;; if no previous clause succeeds, show subtree
+ (outline-show-subtree))))))
+ beg end)))
+ (run-hooks 'outline-view-change-hook)))
+
(defun outline--cycle-state ()
"Return the cycle state of current heading.
Return either 'hide-all, 'headings-only, or 'show-all."
diff --git a/lisp/paren.el b/lisp/paren.el
index a1f74f2097e..0065bba72e7 100644
--- a/lisp/paren.el
+++ b/lisp/paren.el
@@ -330,9 +330,7 @@ It is the default value of `show-paren-data-function'."
(let ((open-paren-line-string
(blink-paren-open-paren-line-string openparen))
(message-log-max nil))
- (minibuffer-message
- "Matches %s"
- (substring-no-properties open-paren-line-string)))))
+ (minibuffer-message "Matches %s" open-paren-line-string))))
;; Always set the overlay face, since it varies.
(overlay-put show-paren--overlay 'priority show-paren-priority)
(overlay-put show-paren--overlay 'face face))))))
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index b1bef82842d..b42279415bc 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -744,10 +744,10 @@ The option \"--fullname\" must be included in this value."
output))
-(easy-mmode-defmap gud-minibuffer-local-map
- '(("\C-i" . comint-dynamic-complete-filename))
- "Keymap for minibuffer prompting of gud startup command."
- :inherit minibuffer-local-map)
+(defvar-keymap gud-minibuffer-local-map
+ :doc "Keymap for minibuffer prompting of gud startup command."
+ :parent minibuffer-local-map
+ "C-i" #'comint-dynamic-complete-filename)
(defun gud-query-cmdline (minor-mode &optional init)
(let* ((hist-sym (gud-symbol 'history nil minor-mode))
@@ -869,7 +869,8 @@ the buffer in which this command was invoked."
COMMAND is the prefix for which we seek completion.
CONTEXT is the text before COMMAND on the line."
(let* ((complete-list
- (gud-gdb-run-command-fetch-lines (concat "complete " context command)
+ (gud-gdb-run-command-fetch-lines (concat "server complete "
+ context command)
(current-buffer)
;; From string-match above.
(length context))))
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index edd3139a7aa..5889f2ab670 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -3216,11 +3216,13 @@ detecting a prompt at the end of the buffer."
(defun python-shell-send-string-no-output (string &optional process)
"Send STRING to PROCESS and inhibit output.
Return the output."
- (let ((process (or process (python-shell-get-process-or-error)))
- (comint-preoutput-filter-functions
- '(python-shell-output-filter))
- (python-shell-output-filter-in-progress t)
- (inhibit-quit t))
+ (or process (setq process (python-shell-get-process-or-error)))
+ (cl-letf (((process-filter process)
+ (lambda (_proc str)
+ (with-current-buffer (process-buffer process)
+ (python-shell-output-filter str))))
+ (python-shell-output-filter-in-progress t)
+ (inhibit-quit t))
(or
(with-local-quit
(python-shell-send-string string process)
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index 9ce63a8f8a1..37e2159782f 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -118,16 +118,16 @@ When it is a file name, it should be the \"expanded\" version.")
(defcustom xref-file-name-display 'project-relative
"Style of file name display in *xref* buffers.
-If the value is the symbol `abs', the default, show the file names
-in their full absolute form.
+If the value is the symbol `abs', show the file names in their
+full absolute form.
If `nondirectory', show only the nondirectory (a.k.a. \"base name\")
part of the file name.
-If `project-relative', show only the file name relative to the
-current project root. If there is no current project, or if the
-file resides outside of its root, show that particular file name
-in its full absolute form."
+If `project-relative', the default, show only the file name
+relative to the current project root. If there is no current
+project, or if the file resides outside of its root, show that
+particular file name in its full absolute form."
:type '(choice (const :tag "absolute file name" abs)
(const :tag "nondirectory file name" nondirectory)
(const :tag "relative to project root" project-relative))
@@ -738,11 +738,20 @@ quit the *xref* buffer."
"Perform interactive replacement of FROM with TO in all displayed xrefs.
This command interactively replaces FROM with TO in the names of the
-references displayed in the current *xref* buffer."
+references displayed in the current *xref* buffer.
+
+When called interactively, it uses '.*' as FROM, which means
+replace the whole name. Unless called with prefix argument, in
+which case the user is prompted for both FROM and TO."
(interactive
- (let ((fr (read-regexp "Xref query-replace (regexp)" ".*")))
- (list fr
- (read-regexp (format "Xref query-replace (regexp) %s with: " fr)))))
+ (let* ((fr
+ (if current-prefix-arg
+ (read-regexp "Query-replace (regexp)" ".*")
+ ".*"))
+ (prompt (if current-prefix-arg
+ (format "Query-replace (regexp) %s with: " fr)
+ "Query-replace all matches with: ")))
+ (list fr (read-regexp prompt))))
(let* (item xrefs iter)
(save-excursion
(while (setq item (xref--search-property 'xref-item))
@@ -1469,6 +1478,22 @@ is nil, prompt only if there's no usable symbol at point."
(interactive (list (xref--read-identifier "Find references of: ")))
(xref--find-xrefs identifier 'references identifier nil))
+(defun xref-find-references-and-replace (from to)
+ "Replace all references to identifier FROM with TO."
+ (interactive
+ (let ((common
+ (query-replace-read-args "Query replace identifier" nil)))
+ (list (nth 0 common) (nth 1 common))))
+ (require 'xref)
+ (with-current-buffer
+ (let ((xref-show-xrefs-function
+ ;; Some future-proofing (bug#44905).
+ (custom--standard-value 'xref-show-xrefs-function))
+ ;; Disable auto-jumping, it will mess up replacement logic.
+ xref-auto-jump-to-first-xref)
+ (xref-find-references from))
+ (xref-query-replace-in-results ".*" to)))
+
;;;###autoload
(defun xref-find-definitions-at-mouse (event)
"Find the definition of identifier at or around mouse click.
diff --git a/lisp/simple.el b/lisp/simple.el
index c73c94b53ad..8b1e7fe78b0 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -2957,7 +2957,8 @@ undo record: if we undo from 4, `pending-undo-list' will be at 3,
(defcustom undo-no-redo nil
"If t, `undo' doesn't go through redo entries."
- :type 'boolean)
+ :type 'boolean
+ :group 'undo)
(defvar pending-undo-list nil
"Within a run of consecutive undo commands, list remaining to be undone.
diff --git a/lisp/subr.el b/lisp/subr.el
index b0d2ab623b1..81c02338531 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -4294,11 +4294,13 @@ in which case `save-window-excursion' cannot help."
(defmacro with-output-to-temp-buffer (bufname &rest body)
"Bind `standard-output' to buffer BUFNAME, eval BODY, then show that buffer.
-This construct makes buffer BUFNAME empty before running BODY.
-It does not make the buffer current for BODY.
-Instead it binds `standard-output' to that buffer, so that output
-generated with `prin1' and similar functions in BODY goes into
-the buffer.
+This is a convenience macro meant for displaying help buffers and
+the like. It empties the BUFNAME buffer before evaluating BODY
+and disables undo in that buffer.
+
+It does not make the buffer current for BODY. Instead it binds
+`standard-output' to that buffer, so that output generated with
+`prin1' and similar functions in BODY goes into the buffer.
At the end of BODY, this marks buffer BUFNAME unmodified and displays
it in a window, but does not select it. The normal way to do this is
@@ -6555,7 +6557,7 @@ signalled. If NOERROR, the non-loop parts of the chain is returned."
(eq func orig-func))
(if noerror
(throw 'loop chain)
- (error "Alias loop for `%s'" orig-func)))
+ (signal 'cyclic-function-indirection (list orig-func))))
(push func chain))
chain))))
diff --git a/lisp/term/x-win.el b/lisp/term/x-win.el
index e52e488edab..cd63c9208ba 100644
--- a/lisp/term/x-win.el
+++ b/lisp/term/x-win.el
@@ -1527,16 +1527,32 @@ This uses `icon-map-list' to map icon file names to stock icon names."
(defvar x-preedit-overlay nil
"The overlay currently used to display preedit text from a compose sequence.")
+;; With some input methods, text gets inserted before Emacs is told to
+;; remove any preedit text that was displayed, which causes both the
+;; preedit overlay and the text to be visible for a brief period of
+;; time. This pre-command-hook clears the overlay before any command
+;; and should be set whenever a preedit overlay is visible.
+(defun x-clear-preedit-text ()
+ "Clear the pre-edit overlay and remove itself from pre-command-hook.
+This function should be installed in `pre-command-hook' whenever
+preedit text is displayed."
+ (when x-preedit-overlay
+ (delete-overlay x-preedit-overlay)
+ (setq x-preedit-overlay nil))
+ (remove-hook 'pre-command-hook #'x-clear-preedit-text))
+
(defun x-preedit-text (event)
"Display preedit text from a compose sequence in EVENT.
EVENT is a preedit-text event."
(interactive "e")
(when x-preedit-overlay
(delete-overlay x-preedit-overlay)
- (setq x-preedit-overlay nil))
+ (setq x-preedit-overlay nil)
+ (remove-hook 'pre-command-hook #'x-clear-preedit-text))
(when (nth 1 event)
(let ((string (propertize (nth 1 event) 'face '(:underline t))))
(setq x-preedit-overlay (make-overlay (point) (point)))
+ (add-hook 'pre-command-hook #'x-clear-preedit-text)
(overlay-put x-preedit-overlay 'window (selected-window))
(overlay-put x-preedit-overlay 'before-string
(if x-display-cursor-at-start-of-preedit-string
diff --git a/lisp/vc/pcvs-info.el b/lisp/vc/pcvs-info.el
index 11d14f95766..b48a4a1cbf1 100644
--- a/lisp/vc/pcvs-info.el
+++ b/lisp/vc/pcvs-info.el
@@ -130,9 +130,11 @@ to confuse some users sometimes."
(defvar cvs-bakprefix ".#"
"The prefix that CVS prepends to files when rcsmerge'ing.")
-(easy-mmode-defmap cvs-status-map
- '(([(mouse-2)] . cvs-mode-toggle-mark))
- "Local keymap for text properties of status.")
+(declare-function cvs-mode-toggle-mark "pcvs" (e))
+
+(defvar-keymap cvs-status-map
+ :doc "Local keymap for text properties of status."
+ "<mouse-2>" #'cvs-mode-toggle-mark)
;; Constructor:
diff --git a/src/buffer.c b/src/buffer.c
index 10ac91915c6..a3091015d9b 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -1247,7 +1247,7 @@ buffer_local_value (Lisp_Object variable, Lisp_Object buffer)
{ /* Look in local_var_alist. */
struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
XSETSYMBOL (variable, sym); /* Update In case of aliasing. */
- result = Fassoc (variable, BVAR (buf, local_var_alist), Qnil);
+ result = assq_no_quit (variable, BVAR (buf, local_var_alist));
if (!NILP (result))
{
if (blv->fwd.fwdptr)
diff --git a/src/data.c b/src/data.c
index 5d0790692b7..f287c38fcdf 100644
--- a/src/data.c
+++ b/src/data.c
@@ -2103,7 +2103,7 @@ Instead, use `add-hook' and specify t for the LOCAL argument. */)
/* Make sure this buffer has its own value of symbol. */
XSETSYMBOL (variable, sym); /* Update in case of aliasing. */
- tem = Fassq (variable, BVAR (current_buffer, local_var_alist));
+ tem = assq_no_quit (variable, BVAR (current_buffer, local_var_alist));
if (NILP (tem))
{
if (let_shadows_buffer_binding_p (sym))
@@ -2183,7 +2183,7 @@ From now on the default value will apply in this buffer. Return VARIABLE. */)
/* Get rid of this buffer's alist element, if any. */
XSETSYMBOL (variable, sym); /* Propagate variable indirection. */
- tem = Fassq (variable, BVAR (current_buffer, local_var_alist));
+ tem = assq_no_quit (variable, BVAR (current_buffer, local_var_alist));
if (!NILP (tem))
bset_local_var_alist
(current_buffer,
@@ -2224,7 +2224,7 @@ Also see `buffer-local-boundp'.*/)
case SYMBOL_PLAINVAL: return Qnil;
case SYMBOL_LOCALIZED:
{
- Lisp_Object tail, elt, tmp;
+ Lisp_Object tmp;
struct Lisp_Buffer_Local_Value *blv = SYMBOL_BLV (sym);
XSETBUFFER (tmp, buf);
XSETSYMBOL (variable, sym); /* Update in case of aliasing. */
@@ -2232,13 +2232,9 @@ Also see `buffer-local-boundp'.*/)
if (EQ (blv->where, tmp)) /* The binding is already loaded. */
return blv_found (blv) ? Qt : Qnil;
else
- for (tail = BVAR (buf, local_var_alist); CONSP (tail); tail = XCDR (tail))
- {
- elt = XCAR (tail);
- if (EQ (variable, XCAR (elt)))
- return Qt;
- }
- return Qnil;
+ return NILP (assq_no_quit (variable, BVAR (buf, local_var_alist)))
+ ? Qnil
+ : Qt;
}
case SYMBOL_FORWARDED:
{
diff --git a/src/emacsgtkfixed.c b/src/emacsgtkfixed.c
index da56031e2a4..a38ba35ad80 100644
--- a/src/emacsgtkfixed.c
+++ b/src/emacsgtkfixed.c
@@ -164,13 +164,9 @@ XSetWMSizeHints (Display *d,
if ((hints->flags & PMinSize) && f)
{
-#ifdef HAVE_PGTK
- int w = f->output_data.pgtk->size_hints.min_width;
- int h = f->output_data.pgtk->size_hints.min_height;
-#else
int w = f->output_data.x->size_hints.min_width;
int h = f->output_data.x->size_hints.min_height;
-#endif
+
data[5] = w;
data[6] = h;
}
diff --git a/src/frame.c b/src/frame.c
index e5d74edc168..959f0c9c142 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -2385,7 +2385,7 @@ DEFUN ("delete-frame", Fdelete_frame, Sdelete_frame, 0, 2, "",
doc: /* Delete FRAME, eliminating it from use.
FRAME must be a live frame and defaults to the selected one.
-When `undelete-frame-mode' is enabled, the 16 most recently deleted
+When `undelete-frame-max' is more than 0, the most recently deleted
frames can be undeleted with `undelete-frame', which see.
A frame may not be deleted if its minibuffer serves as surrogate
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 36ed55bc039..48e981d0d9a 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -6256,13 +6256,16 @@ xg_widget_key_press_event_cb (GtkWidget *widget, GdkEvent *event,
}
XNoOp (FRAME_X_DISPLAY (f));
+#ifdef USABLE_SIGIO
+ raise (SIGIO);
+#endif
return true;
}
bool
xg_filter_key (struct frame *frame, XEvent *xkey)
{
- GdkEvent *xg_event = gdk_event_new ((xkey->type == ButtonPress
+ GdkEvent *xg_event = gdk_event_new ((xkey->type == KeyPress
#ifdef HAVE_XINPUT2
|| (xkey->type == GenericEvent
&& xkey->xgeneric.evtype == XI_KeyPress)
diff --git a/src/haiku_draw_support.cc b/src/haiku_draw_support.cc
index 5d355ac2058..270a619b89b 100644
--- a/src/haiku_draw_support.cc
+++ b/src/haiku_draw_support.cc
@@ -313,7 +313,7 @@ BView_DrawBitmapWithEraseOp (void *view, void *bitmap, int x,
BRect bounds = bc.Bounds ();
for (int y = 0; y < BE_RECT_HEIGHT (bounds); ++y)
{
- for (int x = 0; x <= BE_RECT_WIDTH (bounds); ++x)
+ for (int x = 0; x < BE_RECT_WIDTH (bounds); ++x)
{
if (bits[y * (stride / 4) + x] == 0xFF000000)
bits[y * (stride / 4) + x] = RGB_COLOR_UINT32 (low_color);
diff --git a/src/haiku_support.cc b/src/haiku_support.cc
index d49e319b98c..22605335c55 100644
--- a/src/haiku_support.cc
+++ b/src/haiku_support.cc
@@ -1861,7 +1861,7 @@ BWindow_retitle (void *window, const char *title)
void
BWindow_resize (void *window, int width, int height)
{
- ((BWindow *) window)->ResizeTo (width, height);
+ ((BWindow *) window)->ResizeTo (width - 1, height - 1);
}
/* Activate WINDOW, making it the subject of keyboard focus and
@@ -2224,7 +2224,11 @@ BWindow_set_tooltip_decoration (void *window)
if (!w->LockLooper ())
gui_abort ("Failed to lock window while setting ttip decoration");
w->SetLook (B_BORDERED_WINDOW_LOOK);
- w->SetFeel (B_FLOATING_APP_WINDOW_FEEL);
+ w->SetFeel (kMenuWindowFeel);
+ w->SetFlags (B_NOT_ZOOMABLE
+ | B_NOT_MINIMIZABLE
+ | B_AVOID_FRONT
+ | B_AVOID_FOCUS);
w->UnlockLooper ();
}
@@ -2818,7 +2822,7 @@ be_popup_file_dialog (int open_p, const char *default_dir, int must_match_p, int
enum haiku_event_type type;
char *ptr = NULL;
- if (!haiku_read_with_timeout (&type, buf, 200, 100000))
+ if (!haiku_read_with_timeout (&type, buf, 200, 1000000))
{
block_input_function ();
if (type != FILE_PANEL_EVENT)
diff --git a/src/haikuterm.c b/src/haikuterm.c
index 47199c139c6..05f9788f184 100644
--- a/src/haikuterm.c
+++ b/src/haikuterm.c
@@ -55,6 +55,8 @@ struct unhandled_event
uint8_t buffer[200];
};
+static bool any_help_event_p = false;
+
char *
get_keysym_name (int keysym)
{
@@ -370,6 +372,13 @@ haiku_frame_raise_lower (struct frame *f, bool raise_p)
BWindow_sync (FRAME_HAIKU_WINDOW (f));
unblock_input ();
}
+ else
+ {
+ block_input ();
+ BWindow_send_behind (FRAME_HAIKU_WINDOW (f), NULL);
+ BWindow_sync (FRAME_HAIKU_WINDOW (f));
+ unblock_input ();
+ }
}
/* Unfortunately, NOACTIVATE is not implementable on Haiku. */
@@ -2472,10 +2481,7 @@ haiku_default_font_parameter (struct frame *f, Lisp_Object parms)
struct haiku_font_pattern ptn;
ptn.specified = 0;
- if (f->tooltip)
- BFont_populate_plain_family (&ptn);
- else
- BFont_populate_fixed_family (&ptn);
+ BFont_populate_fixed_family (&ptn);
if (ptn.specified & FSPEC_FAMILY)
font = font_open_by_name (f, build_unibyte_string (ptn.family));
@@ -2590,6 +2596,7 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
struct unhandled_event *unhandled_events = NULL;
int button_or_motion_p;
int need_flush = 0;
+ int do_help = 0;
if (!buf)
buf = xmalloc (200);
@@ -2770,8 +2777,9 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
}
haiku_new_focus_frame (x_display_list->focused_frame);
- help_echo_string = Qnil;
- gen_help_event (Qnil, frame, Qnil, Qnil, 0);
+
+ if (any_help_event_p)
+ do_help = -1;
}
else
{
@@ -2816,9 +2824,9 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
remember_mouse_glyph (f, b->x, b->y,
&FRAME_DISPLAY_INFO (f)->last_mouse_glyph);
dpyinfo->last_mouse_glyph_frame = f;
- gen_help_event (help_echo_string, frame, help_echo_window,
- help_echo_object, help_echo_pos);
}
+ else
+ help_echo_string = previous_help_echo_string;
if (!NILP (Vmouse_autoselect_window))
{
@@ -2838,6 +2846,10 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
last_mouse_window = window;
}
+
+ if (!NILP (help_echo_string)
+ || !NILP (previous_help_echo_string))
+ do_help = 1;
}
break;
}
@@ -3235,7 +3247,10 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
struct frame *f = haiku_window_to_frame (b->window);
if (!f)
- continue;
+ {
+ free (b->ref);
+ continue;
+ }
inev.kind = DRAG_N_DROP_EVENT;
inev.arg = build_string_from_utf8 (b->ref);
@@ -3286,6 +3301,28 @@ haiku_read_socket (struct terminal *terminal, struct input_event *hold_quit)
xfree (old);
}
+ if (do_help && !(hold_quit && hold_quit->kind != NO_EVENT))
+ {
+ Lisp_Object help_frame = Qnil;
+
+ if (x_display_list->last_mouse_frame)
+ XSETFRAME (help_frame,
+ x_display_list->last_mouse_frame);
+
+ if (do_help > 0)
+ {
+ any_help_event_p = true;
+ gen_help_event (help_echo_string, help_frame,
+ help_echo_window, help_echo_object,
+ help_echo_pos);
+ }
+ else
+ {
+ help_echo_string = Qnil;
+ gen_help_event (Qnil, help_frame, Qnil, Qnil, 0);
+ }
+ }
+
if (need_flush)
flush_dirty_back_buffers ();
diff --git a/src/pgtkterm.c b/src/pgtkterm.c
index 0155ae991d3..4c38ff5a597 100644
--- a/src/pgtkterm.c
+++ b/src/pgtkterm.c
@@ -153,10 +153,24 @@ static int
evq_flush (struct input_event *hold_quit)
{
struct event_queue_t *evq = &event_q;
- int i, n = evq->nr;
- for (i = 0; i < n; i++)
- kbd_buffer_store_buffered_event (&evq->q[i], hold_quit);
- evq->nr = 0;
+ int n = 0;
+
+ while (evq->nr > 0)
+ {
+ /* kbd_buffer_store_buffered_event may do longjmp, so
+ we need to shift event queue first and pass the event
+ to kbd_buffer_store_buffered_event so that events in
+ queue are not processed twice. Bug#52941 */
+ union buffered_input_event ev = evq->q[0];
+ int i;
+ for (i = 1; i < evq->nr; i++)
+ evq->q[i - 1] = evq->q[i];
+ evq->nr--;
+
+ kbd_buffer_store_buffered_event (&ev, hold_quit);
+ n++;
+ }
+
return n;
}
diff --git a/src/xdisp.c b/src/xdisp.c
index 977d31703fb..c695e466e78 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -19157,7 +19157,8 @@ redisplay_window (Lisp_Object window, bool just_this_one_p)
struct glyph_row *row;
row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
- while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
+ while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos
+ && !row->ends_at_zv_p)
++row;
TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
diff --git a/src/xfaces.c b/src/xfaces.c
index 8064d47c947..e148b5d3987 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -6423,8 +6423,12 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
cached faces since we've looked up these faces, we need to look
them up again. */
if (!default_face)
- default_face = FACE_FROM_ID (f,
- lookup_basic_face (w, f, DEFAULT_FACE_ID));
+ {
+ if (FRAME_FACE_CACHE (f)->used == 0)
+ recompute_basic_faces (f);
+ default_face = FACE_FROM_ID (f,
+ lookup_basic_face (w, f, DEFAULT_FACE_ID));
+ }
}
/* Optimize common cases where we can use the default face. */
diff --git a/src/xfns.c b/src/xfns.c
index ffad0bc3d1a..d73e951754b 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -2643,11 +2643,7 @@ best_xim_style (struct x_display_info *dpyinfo,
int nr_supported = ARRAYELTS (supported_xim_styles);
if (dpyinfo->preferred_xim_style)
- {
- for (j = 0; j < xim->count_styles; ++j)
- if (dpyinfo->preferred_xim_style == xim->supported_styles[j])
- return dpyinfo->preferred_xim_style;
- }
+ return dpyinfo->preferred_xim_style;
for (i = 0; i < nr_supported; ++i)
for (j = 0; j < xim->count_styles; ++j)
diff --git a/src/xsettings.h b/src/xsettings.h
index 266526df101..ccaa36489d0 100644
--- a/src/xsettings.h
+++ b/src/xsettings.h
@@ -21,15 +21,14 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#define XSETTINGS_H
#ifndef HAVE_PGTK
+#include "dispextern.h"
#include <X11/Xlib.h>
#endif
struct x_display_info;
struct pgtk_display_info;
-#ifndef HAVE_PGTK
-typedef struct x_display_info Display_Info;
-#else
+#ifdef HAVE_PGTK
typedef struct pgtk_display_info Display_Info;
#endif
diff --git a/src/xterm.c b/src/xterm.c
index a74c31c3f6e..3328e659301 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -20,6 +20,72 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
/* New display code by Gerd Moellmann <gerd@gnu.org>. */
/* Xt features made by Fred Pierresteguy. */
+/* X window system support for GNU Emacs
+
+ This file is part of the X window system support for GNU Emacs. It
+ contains subroutines comprising the redisplay interface, setting up
+ scroll bars and widgets, and handling input.
+
+ INPUT
+
+ Emacs handles input by running pselect in a loop, which returns
+ whenever there is input available on the connection to the X
+ server. On some systems, Emacs also arranges for any new input on
+ that connection to send an asynchronous signal. Whenever pselect
+ returns, or such a signal is received and input is not blocked,
+ XTread_socket is called and translates X11 events read by Xlib into
+ struct input_events, which are then stored in the keyboard buffer,
+ to be processed and acted upon at some later time. The function
+ handle_one_xevent is responsible for handling core events after
+ they are filtered, and filtering X Input Extension events. It also
+ performs actions on some special events, such as updating the
+ dimensions of a frame after a ConfigureNotify is sent by the X
+ server to inform us that it changed.
+
+ Before such events are translated, an Emacs build with
+ internationalization enabled (the default since X11R6) will filter
+ events through an X Input Method (XIM) or GTK, which might decide
+ to intercept the event and send a different one in its place, for
+ reasons such as enabling the user to insert international
+ characters that aren't on his keyboard by typing a sequence of
+ characters which are. See the function x_filter_event and its
+ callers for more details.
+
+ Events that cause Emacs to quit are treated specially by the code
+ that stores them in the keyboard buffer and generally cause an
+ immediate interrupt. Such an interrupt can lead to a longjmp from
+ the code that stored the keyboard event, which isn't safe inside
+ XTread_socket. To avoid this problem, XTread_socket is provided a
+ special event buffer named hold_quit. When a quit event is
+ encountered, it is stored inside this special buffer, which will
+ cause the keyboard code that called XTread_socket to store it at a
+ later time when it is safe to do so.
+
+ handle_one_xevent will generally have to determine which frame an
+ event should be attributed to. This is not easy, because events
+ can come from multiple X windows, and a frame can also have
+ multiple windows. handle_one_xevent usually calls the function
+ x_any_window_to_frame, which searches for a frame by toplevel
+ window and widget windows. There are also some other functions for
+ searching by specific types of window, such as
+ x_top_window_to_frame (which only searches for frames by toplevel
+ window), and x_menubar_window_to_frame (which will only search
+ through frame menu bars).
+
+ INPUT FOCUS
+
+ Under X, the window where keyboard input is sent is not always
+ explictly defined. When there is a focus window, it receives what
+ is referred to as "explicit focus", but when there is none, it
+ receives "implicit focus" whenever the pointer enters it, and loses
+ that focus when the pointer leaves. When the toplevel window of a
+ frame receives an explicit focus event (FocusIn or FocusOut), we
+ treat that frame as having the current input focus, but when there
+ is no focus window, we treat each frame as having the input focus
+ whenever the pointer enters it, and undo that treatment when the
+ pointer leaves it. See the callers of x_detect_focus_change for
+ more details. */
+
#include <config.h>
#include <stdlib.h>
#include <math.h>
@@ -5923,7 +5989,7 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
if (!f1 && insist > 0)
f1 = SELECTED_FRAME ();
- if (f1)
+ if (f1 && FRAME_X_P (f1))
{
/* Ok, we found a frame. Store all the values.
last_mouse_glyph is a rectangle used to reduce the
@@ -5933,7 +5999,6 @@ XTmouse_position (struct frame **fp, int insist, Lisp_Object *bar_window,
on it, i.e. into the same rectangles that matrices on
the frame are divided into. */
- /* FIXME: what if F1 is not an X frame? */
dpyinfo = FRAME_DISPLAY_INFO (f1);
remember_mouse_glyph (f1, win_x, win_y, &dpyinfo->last_mouse_glyph);
dpyinfo->last_mouse_glyph_frame = f1;
@@ -8308,6 +8373,7 @@ x_filter_event (struct x_display_info *dpyinfo, XEvent *event)
#ifdef USE_GTK
}
else if (f1 && (event->type == KeyPress
+ || event->type == KeyRelease
#ifdef HAVE_XINPUT2
|| xinput_event
#endif
@@ -8369,8 +8435,10 @@ event_handler_gdk (GdkXEvent *gxev, GdkEvent *ev, gpointer data)
&& xev->type == GenericEvent
&& (xev->xgeneric.extension
== dpyinfo->xi2_opcode)
- && (xev->xgeneric.evtype
- == XI_KeyPress))
+ && ((xev->xgeneric.evtype
+ == XI_KeyPress)
+ || (xev->xgeneric.evtype
+ == XI_KeyRelease)))
#endif
))
{
@@ -10643,7 +10711,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (f && xev->evtype == XI_ButtonPress
&& !popup_activated ()
- && !x_window_to_scroll_bar (xev->display, xev->event, 2)
+ && !x_window_to_scroll_bar (dpyinfo->display, xev->event, 2)
&& !FRAME_NO_ACCEPT_FOCUS (f))
{
/* When clicking into a child frame or when clicking
@@ -10816,7 +10884,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
xkey.type = KeyPress;
xkey.serial = xev->serial;
xkey.send_event = xev->send_event;
- xkey.display = xev->display;
+ xkey.display = dpyinfo->display;
xkey.window = xev->event;
xkey.root = xev->root;
xkey.subwindow = xev->child;
@@ -11162,7 +11230,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
xkey.type = KeyRelease;
xkey.serial = xev->serial;
xkey.send_event = xev->send_event;
- xkey.display = xev->display;
+ xkey.display = dpyinfo->display;
xkey.window = xev->event;
xkey.root = xev->root;
xkey.subwindow = xev->child;
@@ -11458,9 +11526,24 @@ handle_one_xevent (struct x_display_info *dpyinfo,
XkbFreeKeyboard (dpyinfo->xkb_desc, XkbAllComponentsMask, True);
dpyinfo->xkb_desc = NULL;
}
-
- x_find_modifier_meanings (dpyinfo);
}
+ else
+ {
+ dpyinfo->xkb_desc = XkbGetMap (dpyinfo->display,
+ (XkbKeySymsMask
+ | XkbKeyTypesMask
+ | XkbModifierMapMask
+ | XkbVirtualModsMask),
+ XkbUseCoreKbd);
+
+ if (dpyinfo->xkb_desc)
+ XkbGetNames (dpyinfo->display,
+ XkbGroupNamesMask | XkbVirtualModNamesMask,
+ dpyinfo->xkb_desc);
+ }
+
+ XkbRefreshKeyboardMapping (&xkbevent->map);
+ x_find_modifier_meanings (dpyinfo);
}
}
#endif
@@ -12617,9 +12700,11 @@ xim_initialize (struct x_display_info *dpyinfo, char *resource_name)
ret = XRegisterIMInstantiateCallback
(dpyinfo->display, dpyinfo->rdb, xim_inst->resource_name,
emacs_class, xim_instantiate_callback,
- /* This is XPointer in XFree86 but (XPointer *)
- on Tru64, at least, hence the configure test. */
- (XRegisterIMInstantiateCallback_arg6) xim_inst);
+ /* This is XPointer in XFree86 but (XPointer *) on Tru64, at
+ least, but the configure test doesn't work because
+ xim_instantiate_callback can either be XIMProc or
+ XIDProc, so just cast to void *. */
+ (void *) xim_inst);
eassert (ret == True);
#else /* not HAVE_X11R6_XIM */
xim_open_dpy (dpyinfo, resource_name);
@@ -12644,8 +12729,7 @@ xim_close_dpy (struct x_display_info *dpyinfo)
{
Bool ret = XUnregisterIMInstantiateCallback
(dpyinfo->display, dpyinfo->rdb, xim_inst->resource_name,
- emacs_class, xim_instantiate_callback,
- (XRegisterIMInstantiateCallback_arg6) xim_inst);
+ emacs_class, xim_instantiate_callback, (void *) xim_inst);
eassert (ret == True);
}
xfree (xim_inst->resource_name);
diff --git a/src/xwidget.c b/src/xwidget.c
index 45879b15cbe..fce0aafb099 100644
--- a/src/xwidget.c
+++ b/src/xwidget.c
@@ -1855,7 +1855,7 @@ webkit_js_to_lisp (JSCValue *value)
const gint32 dlen = jsc_value_to_int32 (len);
Lisp_Object obj;
- if (! (0 <= dlen && dlen < PTRDIFF_MAX + 1.0))
+ if (! (0 <= dlen && dlen < G_MAXINT32 + 1))
memory_full (SIZE_MAX);
ptrdiff_t n = dlen;
diff --git a/test/lisp/emacs-lisp/edebug-tests.el b/test/lisp/emacs-lisp/edebug-tests.el
index d238bffdaa1..35259a796a0 100644
--- a/test/lisp/emacs-lisp/edebug-tests.el
+++ b/test/lisp/emacs-lisp/edebug-tests.el
@@ -1094,5 +1094,15 @@ This avoids potential duplicate definitions (Bug#41988)."
(edebug-new-definition name))))
(should-error (eval-buffer) :type 'invalid-read-syntax))))
+(ert-deftest edebug-tests-inline ()
+ "Check that Edebug can instrument inline functions (Bug#53068)."
+ (with-temp-buffer
+ (print '(define-inline edebug-tests-inline (arg)
+ (inline-quote ,arg))
+ (current-buffer))
+ (let ((edebug-all-defs t)
+ (edebug-initial-mode 'Go-nonstop))
+ (eval-buffer))))
+
(provide 'edebug-tests)
;;; edebug-tests.el ends here
diff --git a/test/lisp/ffap-tests.el b/test/lisp/ffap-tests.el
index aebc9b6dbb9..0fdc31e8b61 100644
--- a/test/lisp/ffap-tests.el
+++ b/test/lisp/ffap-tests.el
@@ -141,6 +141,23 @@ left alone when opening a URL in an external browser."
(let (kill-buffer-query-functions)
(kill-buffer (call-interactively #'find-file-at-point)))))))
+(ert-deftest ffap-test-path ()
+ (skip-unless (file-exists-p "/bin"))
+ (skip-unless (file-exists-p "/usr/bin"))
+ (with-temp-buffer
+ (insert "/usr/bin:/bin")
+ (goto-char (point-min))
+ (should (equal (ffap-file-at-point) "/usr/bin")))
+ (with-temp-buffer
+ (insert "/usr/bin:/bin")
+ (goto-char (point-min))
+ (search-forward ":")
+ (should (equal (ffap-file-at-point) "/bin")))
+ (with-temp-buffer
+ (insert ":/bin")
+ (goto-char (point-min))
+ (should (equal (ffap-file-at-point) nil))))
+
(provide 'ffap-tests)
;;; ffap-tests.el ends here
diff --git a/test/lisp/net/mailcap-resources/mailcap b/test/lisp/net/mailcap-resources/mailcap
new file mode 100644
index 00000000000..ad3f7404fda
--- /dev/null
+++ b/test/lisp/net/mailcap-resources/mailcap
@@ -0,0 +1,9 @@
+audio/ogg; mpv %s
+audio/flac; mpv %s
+audio/x-wav; aplay %s
+text/*; emacsclient -t %s
+application/pdf; acroread %s; test=false
+application/pdf; evince %s
+application/pdf; okular %s
+image/*; eog %s
+image/svg+xml; inkscape %s
diff --git a/test/lisp/net/mailcap-resources/test.test b/test/lisp/net/mailcap-resources/test.test
new file mode 100644
index 00000000000..9daeafb9864
--- /dev/null
+++ b/test/lisp/net/mailcap-resources/test.test
@@ -0,0 +1 @@
+test
diff --git a/test/lisp/net/mailcap-tests.el b/test/lisp/net/mailcap-tests.el
index 362cb22bb2f..b439c08c791 100644
--- a/test/lisp/net/mailcap-tests.el
+++ b/test/lisp/net/mailcap-tests.el
@@ -63,4 +63,74 @@
(append mailcap-tests-path-extensions
mailcap-tests-mime-extensions))))
+(defmacro with-pristine-mailcap (&rest body)
+ ;; We only want the mailcap info we define ourselves.
+ `(let (mailcap--computed-mime-data
+ mailcap-mime-data
+ mailcap-user-mime-data)
+ ;; `mailcap-mime-info' calls `mailcap-parse-mailcaps' which parses
+ ;; the system's mailcaps. We don't want that for our test.
+ (cl-letf (((symbol-function 'mailcap-parse-mailcaps) #'ignore))
+ ,@body)))
+
+(ert-deftest mailcap-parsing-and-mailcap-mime-info ()
+ (with-pristine-mailcap
+ ;; One mailcap entry has a test=false field. The shell command
+ ;; execution errors when running the tests from the Makefile
+ ;; because then HOME=/nonexistent.
+ (ert-with-temp-directory home
+ (setenv "HOME" home)
+ ;; Now parse our resource mailcap file.
+ (mailcap-parse-mailcap (ert-resource-file "mailcap"))
+
+ ;; Assert that we get what we have defined.
+ (dolist (type '("audio/ogg" "audio/flac"))
+ (should (string= "mpv %s" (mailcap-mime-info type))))
+ (should (string= "aplay %s" (mailcap-mime-info "audio/x-wav")))
+ (should (string= "emacsclient -t %s"
+ (mailcap-mime-info "text/plain")))
+ ;; evince is chosen because acroread has test=false and okular
+ ;; comes later.
+ (should (string= "evince %s"
+ (mailcap-mime-info "application/pdf")))
+ (should (string= "inkscape %s"
+ (mailcap-mime-info "image/svg+xml")))
+ (should (string= "eog %s"
+ (mailcap-mime-info "image/jpg")))
+ ;; With REQUEST being a number, all fields of the selected entry
+ ;; should be returned.
+ (should (equal '((viewer . "evince %s")
+ (type . "application/pdf"))
+ (mailcap-mime-info "application/pdf" 1)))
+ ;; With 'all, all applicable entries should be returned.
+ (should (equal '(((viewer . "evince %s")
+ (type . "application/pdf"))
+ ((viewer . "okular %s")
+ (type . "application/pdf")))
+ (mailcap-mime-info "application/pdf" 'all)))
+ (let* ((c nil)
+ (toggle (lambda (_) (setq c (not c)))))
+ (mailcap-add "audio/ogg" "toggle %s" toggle)
+ (should (string= "toggle %s" (mailcap-mime-info "audio/ogg")))
+ ;; The test results are cached, so in order to have the test
+ ;; re-evaluated, one needs to clear the cache.
+ (setq mailcap-viewer-test-cache nil)
+ (should (string= "mpv %s" (mailcap-mime-info "audio/ogg")))
+ (setq mailcap-viewer-test-cache nil)
+ (should (string= "toggle %s" (mailcap-mime-info "audio/ogg")))))))
+
+(defvar mailcap--test-result nil)
+(defun mailcap--test-viewer ()
+ (setq mailcap--test-result (string= (buffer-string) "test\n")))
+
+(ert-deftest mailcap-view-file ()
+ (with-pristine-mailcap
+ ;; Try using a lambda as viewer and check wether
+ ;; `mailcap-view-file' works correctly.
+ (let* ((mailcap-mime-extensions '((".test" . "test/test"))))
+ (mailcap-add "test/test" 'mailcap--test-viewer)
+ (save-window-excursion
+ (mailcap-view-file (ert-resource-file "test.test")))
+ (should mailcap--test-result))))
+
;;; mailcap-tests.el ends here
diff --git a/test/lisp/so-long-tests/spelling-tests.el b/test/lisp/so-long-tests/spelling-tests.el
index 09ffa3c8006..ce4b0844c99 100644
--- a/test/lisp/so-long-tests/spelling-tests.el
+++ b/test/lisp/so-long-tests/spelling-tests.el
@@ -36,12 +36,11 @@
;; make lisp/so-long-tests/spelling-tests SELECTOR=t
;; Only define the test if spell-checking is possible.
-(when (and ispell-program-name
- (executable-find ispell-program-name)
- (condition-case ()
- (progn (ispell-check-version) t)
- (error nil))
- (member "british" (ispell-valid-dictionary-list)))
+(when (ignore-errors
+ (and ispell-program-name
+ (executable-find ispell-program-name)
+ (progn (ispell-check-version) t)
+ (member "british" (ispell-valid-dictionary-list))))
(ert-deftest so-long-spelling ()
"Check the spelling in the source code."
:tags '(:unstable) ;; It works for me, but I'm not sure about others.
@@ -51,9 +50,9 @@
;; The Emacs test Makefile's use of HOME=/nonexistent triggers an error
;; when starting the inferior ispell process, so we set HOME to a valid
;; (but empty) temporary directory for this test.
- (ert-with-temp-file tmpdir
- :directory t
- :suffix "so-long.ispell"
+ (ert-with-temp-directory tmpdir
+ :prefix "so-long."
+ :suffix ".ispell"
(let* ((process-environment (cons (format "HOME=%s" tmpdir)
process-environment))
(find-spelling-mistake