summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuan Fu <casouri@gmail.com>2024-12-01 17:52:16 -0800
committerYuan Fu <casouri@gmail.com>2024-12-01 17:52:16 -0800
commit4afd1eca3662eda052d0017f83b4baa1f6131e8b (patch)
tree10c2a2f0d338b8fb330fbbc9b21f296271b73ee2
parent676ff9fd7c083598b2955a463774283768d8e209 (diff)
parentcf4f1387a6561be7cd7387b766df4386a0fa472f (diff)
Merge from emacs-30
cf4f1387a65 ; Update tree-sitter manual 3c7687c1dd1 Allow passing nil to treesit-node-match-p (bug#74612) 748b19e56e8 Update to version 2.58 of librsvg API (bug#74606) 4c67f636c08 Fix decoding of non-ASCII email attachments bd8a6f70fb9 Prevent "Selecting deleted buffer" error with dabbrev-expand 0a753603a53 ; (dictionary-search-interface): Fix bug#74511.
-rw-r--r--doc/lispref/parsing.texi32
-rw-r--r--lisp/dabbrev.el6
-rw-r--r--lisp/mail/rfc2231.el2
-rw-r--r--lisp/net/dictionary.el1
-rw-r--r--src/image.c26
-rw-r--r--src/treesit.c5
-rw-r--r--test/lisp/dabbrev-tests.el34
7 files changed, 93 insertions, 13 deletions
diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi
index 20b1085b46c..9fe828d8512 100644
--- a/doc/lispref/parsing.texi
+++ b/doc/lispref/parsing.texi
@@ -1553,7 +1553,11 @@ The ``things'' feature in Emacs is independent of the pattern matching
feature of tree-sitter, and comparatively less powerful, but more
suitable for navigation and traversing the parse tree.
-You can define things with @code{treesit-thing-settings}.
+@findex treesit-thing-definition
+@findex treesit-thing-defined-p
+You can define things with @var{treesit-thing-settings}, retrieve the
+predicate of a defined thing with @code{treesit-thing-definition}, and
+test if a thing is defined with @code{treesit-thing-defined-p}.
@defvar treesit-thing-settings
This is an alist of thing definitions for each language. The key of
@@ -1609,6 +1613,25 @@ functions listed elsewhere also utilize the thing feature, e.g.,
tree-traversing functions like @code{treesit-search-forward},
@code{treesit-induce-sparse-tree}, etc. @xref{Retrieving Nodes}.
+@defun treesit-node-match-p node thing &optional ignore-missing
+This function checks whether @var{node} is a @var{thing}.
+
+If @var{node} is a @var{thing}, return non-@code{nil}, otherwise return
+@code{nil}. For convenience, if @code{node} is @code{nil}, this
+function just returns @code{nil}.
+
+The @var{thing} can be either a thing symbol like @code{defun}, or
+simply a predicate that defines a thing, like
+@code{"function_definition"}, or @w{@code{(or comment string)}}.
+
+By default, if @var{thing} is undefined or malformed, this function
+signals @code{treesit-invalid-predicate} error. If @var{ignore-missing}
+is @code{t}, this function doesn't signal the error when @var{thing} is
+undefined and just returns @code{nil}; but it still signals the error if
+@var{thing} is a malformed predicate.
+
+@end defun
+
@defun treesit-thing-prev position thing
This function returns the first node before @var{position} that is the
specified @var{thing}. If no such node exists, it returns @code{nil}.
@@ -1616,8 +1639,7 @@ It's guaranteed that, if a node is returned, the node's end position is
less or equal to @var{position}. In other words, this function never
returns a node that encloses @var{position}.
-@var{thing} can be either a thing symbol like @code{defun}, or simply a
-thing definition like @code{"function_definition"}.
+Again, @var{thing} can be either a symbol or a predicate.
@end defun
@defun treesit-thing-next position thing
@@ -1641,7 +1663,7 @@ A positive @var{arg} means moving forward that many instances of
@code{end}, stop at the end of @var{thing}.
Like in @code{treesit-thing-prev}, @var{thing} can be a thing symbol
-defined in @code{treesit-thing-settings}, or a thing definition.
+defined in @code{treesit-thing-settings}, or a predicate.
@var{tactic} determines how this function moves between things. It can
be @code{nested}, @code{top-level}, @code{restricted}, or @code{nil}.
@@ -1668,7 +1690,7 @@ i.e., start position must be strictly greater than @var{position}, and end
position must be strictly less than @var{position}.
@var{thing} can be either a thing symbol defined in
-@code{treesit-thing-settings}, or a thing definition.
+@code{treesit-thing-settings}, or a predicate.
@end defun
@findex treesit-beginning-of-thing
diff --git a/lisp/dabbrev.el b/lisp/dabbrev.el
index bbe6a64b626..84306fb3ae7 100644
--- a/lisp/dabbrev.el
+++ b/lisp/dabbrev.el
@@ -472,8 +472,10 @@ See also `dabbrev-abbrev-char-regexp' and \\[dabbrev-completion]."
;; minibuffer.
(window-buffer (get-mru-window)))
;; Otherwise, if we found the expansion in another
- ;; buffer, use that buffer for further expansions.
- (dabbrev--last-buffer-found dabbrev--last-buffer-found)
+ ;; buffer and that buffer is still live, use that
+ ;; buffer for further expansions.
+ ((buffer-live-p dabbrev--last-buffer-found)
+ dabbrev--last-buffer-found)
;; Otherwise, use the buffer where we invoked
;; dabbrev-expand.
(t (current-buffer))))
diff --git a/lisp/mail/rfc2231.el b/lisp/mail/rfc2231.el
index 33324cafb5b..632e270a922 100644
--- a/lisp/mail/rfc2231.el
+++ b/lisp/mail/rfc2231.el
@@ -193,7 +193,7 @@ must never cause a Lisp error."
(push (list attribute value encoded) cparams))
;; Repetition of a part; do nothing.
((and elem
- (null number))
+ (null part))
)
;; Concatenate continuation parts.
(t
diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el
index 58c2e9771ba..42fb8c57b40 100644
--- a/lisp/net/dictionary.el
+++ b/lisp/net/dictionary.el
@@ -317,6 +317,7 @@ Otherwise, `dictionary-search' displays definitions in a *Dictionary* buffer."
dictionary-read-dictionary-function)
vals))
(set-default-toplevel-value symbol value))
+ :initialize #'custom-initialize-changed
:version "30.1")
(defface dictionary-word-definition-face
diff --git a/src/image.c b/src/image.c
index db7f6acd171..88b0f91413e 100644
--- a/src/image.c
+++ b/src/image.c
@@ -11706,7 +11706,11 @@ DEF_DLL_FN (void, rsvg_handle_get_dimensions,
DEF_DLL_FN (gboolean, rsvg_handle_set_stylesheet,
(RsvgHandle *, const guint8 *, gsize, GError **));
# endif
+# if LIBRSVG_CHECK_VERSION (2, 58, 0)
+DEF_DLL_FN (GdkPixbuf *, rsvg_handle_get_pixbuf_and_error, (RsvgHandle *, GError **));
+# else
DEF_DLL_FN (GdkPixbuf *, rsvg_handle_get_pixbuf, (RsvgHandle *));
+# endif
DEF_DLL_FN (int, gdk_pixbuf_get_width, (const GdkPixbuf *));
DEF_DLL_FN (int, gdk_pixbuf_get_height, (const GdkPixbuf *));
DEF_DLL_FN (guchar *, gdk_pixbuf_get_pixels, (const GdkPixbuf *));
@@ -11765,8 +11769,11 @@ init_svg_functions (void)
#if LIBRSVG_CHECK_VERSION (2, 48, 0)
LOAD_DLL_FN (library, rsvg_handle_set_stylesheet);
#endif
+#if LIBRSVG_CHECK_VERSION (2, 58, 0)
+ LOAD_DLL_FN (library, rsvg_handle_get_pixbuf_and_error);
+#else
LOAD_DLL_FN (library, rsvg_handle_get_pixbuf);
-
+#endif
LOAD_DLL_FN (gdklib, gdk_pixbuf_get_width);
LOAD_DLL_FN (gdklib, gdk_pixbuf_get_height);
LOAD_DLL_FN (gdklib, gdk_pixbuf_get_pixels);
@@ -11811,7 +11818,11 @@ init_svg_functions (void)
# if LIBRSVG_CHECK_VERSION (2, 48, 0)
# undef rsvg_handle_set_stylesheet
# endif
-# undef rsvg_handle_get_pixbuf
+# if LIBRSVG_CHECK_VERSION (2, 58, 0)
+# undef rsvg_handle_get_pixbuf_and_error
+# else
+# undef rsvg_handle_get_pixbuf
+# endif
# if LIBRSVG_CHECK_VERSION (2, 32, 0)
# undef g_file_new_for_path
# undef g_memory_input_stream_new_from_data
@@ -11852,7 +11863,11 @@ init_svg_functions (void)
# if LIBRSVG_CHECK_VERSION (2, 48, 0)
# define rsvg_handle_set_stylesheet fn_rsvg_handle_set_stylesheet
# endif
-# define rsvg_handle_get_pixbuf fn_rsvg_handle_get_pixbuf
+# if LIBRSVG_CHECK_VERSION (2, 58, 0)
+# define rsvg_handle_get_pixbuf_and_error fn_rsvg_handle_get_pixbuf_and_error
+# else
+# define rsvg_handle_get_pixbuf fn_rsvg_handle_get_pixbuf
+# endif
# if LIBRSVG_CHECK_VERSION (2, 32, 0)
# define g_file_new_for_path fn_g_file_new_for_path
# define g_memory_input_stream_new_from_data \
@@ -12357,8 +12372,13 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
/* We can now get a valid pixel buffer from the svg file, if all
went ok. */
+#if LIBRSVG_CHECK_VERSION (2, 58, 0)
+ pixbuf = rsvg_handle_get_pixbuf_and_error (rsvg_handle, &err);
+ if (err) goto rsvg_error;
+#else
pixbuf = rsvg_handle_get_pixbuf (rsvg_handle);
if (!pixbuf) goto rsvg_error;
+#endif
g_object_unref (rsvg_handle);
xfree (wrapped_contents);
diff --git a/src/treesit.c b/src/treesit.c
index 5e1e9b01059..2372944e166 100644
--- a/src/treesit.c
+++ b/src/treesit.c
@@ -4148,7 +4148,8 @@ PREDICATE can be a symbol representing a thing in
`treesit-thing-settings', or a predicate, like regexp matching node
type, etc. See `treesit-thing-settings' for more details.
-Return non-nil if NODE matches PREDICATE, nil otherwise.
+Return non-nil if NODE matches PREDICATE, nil otherwise. If NODE is
+nil, return nil.
Signals `treesit-invalid-predicate' if there's no definition of THING
in `treesit-thing-settings', or if PREDICATE is malformed. If
@@ -4156,6 +4157,8 @@ IGNORE-MISSING is non-nil, don't signal an error for missing THING
definition, but still signal for malformed PREDICATE. */)
(Lisp_Object node, Lisp_Object predicate, Lisp_Object ignore_missing)
{
+ if (NILP (node)) return Qnil;
+
CHECK_TS_NODE (node);
Lisp_Object parser = XTS_NODE (node)->parser;
diff --git a/test/lisp/dabbrev-tests.el b/test/lisp/dabbrev-tests.el
index 987106aa5af..b5737373875 100644
--- a/test/lisp/dabbrev-tests.el
+++ b/test/lisp/dabbrev-tests.el
@@ -238,7 +238,7 @@ entered."
;; FIXME: Why is dabbrev--reset-global-variables needed here?
(ert-deftest dabbrev-expand-test-minibuffer-3 ()
"Test replacing an expansion in the minibuffer using two buffers.
-The first expansion should befound in the buffer from which the
+The first expansion should be found in the buffer from which the
minibuffer was entered, the replacement should found in another buffer."
(with-dabbrev-test
(find-file (ert-resource-file "INSTALL_BEGIN"))
@@ -275,4 +275,36 @@ minibuffer was entered, the replacement should found in another buffer."
(should (string= (minibuffer-contents) "Indic and"))
(delete-minibuffer-contents))))
+(ert-deftest dabbrev-expand-after-killing-buffer ()
+ "Test expansion after killing buffer containing first expansion.
+Finding successive expansions in another live buffer should succeed, but
+after killing the buffer, expansion should fail with a user-error."
+ ;; FIXME? The message shown by the user-error is in *Messages* but
+ ;; since the test finishes on hitting the user-error, we cannot test
+ ;; further, either for the content of the message or the content of
+ ;; the current buffer, so apparently cannot reproduce what a user
+ ;; entering these commands manually sees.
+ (with-dabbrev-test
+ (with-current-buffer (get-buffer-create "foo")
+ (insert "abc abd"))
+ (switch-to-buffer "*scratch*")
+ (erase-buffer)
+ (execute-kbd-macro (kbd "ab M-/"))
+ (should (string= (buffer-string) "abc"))
+ (execute-kbd-macro (kbd "SPC ab M-/"))
+ (should (string= (buffer-string) "abc abc"))
+ (erase-buffer)
+ (execute-kbd-macro (kbd "abc SPC ab M-/ M-/"))
+ (should (string= (buffer-string) "abc abd"))
+ (kill-buffer "foo")
+ (erase-buffer)
+ (should-error (execute-kbd-macro (kbd "abc SPC ab M-/ M-/"))
+ :type 'user-error)
+ ;; (should (string= (buffer-string) "abc abc"))
+ ;; (with-current-buffer "*Messages*"
+ ;; (goto-char (point-max))
+ ;; (should (string= (buffer-substring (pos-bol) (pos-eol))
+ ;; "No further dynamic expansion for ‘ab’ found")))
+ ))
+
;;; dabbrev-tests.el ends here