commit b18bdbb2c1ea004a3ad8f7c1716fcbc6a61ef927 (HEAD, refs/remotes/origin/master) Author: Juri Linkov Date: Fri Jun 7 09:45:05 2024 +0300 * lisp/buff-menu.el: Mark all entries in outline. (Buffer-menu-mark, Buffer-menu-unmark, Buffer-menu-delete) (Buffer-menu-save): Mark all entries in the outline when `outline-minor-mode' is enabled and point is on the outline heading line (bug#70150). (Buffer-menu-backup-unmark): Support outline heading lines. diff --git a/etc/NEWS b/etc/NEWS index 808cd0562db..5fb1625a76c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1877,7 +1877,8 @@ chat buffers use by default. --- *** New user option 'Buffer-menu-group-by'. It controls how buffers are divided into groups that are displayed with -headings using Outline minor mode. +headings using Outline minor mode. Using commands that mark buffers +on the outline heading line will mark all buffers in the outline. +++ *** New command 'Buffer-menu-toggle-internal'. diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el index d83bf2249e6..c35fa42934c 100644 --- a/lisp/buff-menu.el +++ b/lisp/buff-menu.el @@ -411,19 +411,50 @@ is nil or omitted, and signal an error otherwise." ;;; Commands for modifying Buffer Menu entries. +(defvar outline-minor-mode) +(declare-function outline-on-heading-p "outline" (&optional invisible-ok)) +(declare-function outline-end-of-subtree "outline" ()) +(declare-function outline-previous-heading "outline" ()) + (defun Buffer-menu-mark () "Mark the Buffer menu entry at point for later display. -It will be displayed by the \\\\[Buffer-menu-select] command." +It will be displayed by the \\\\[Buffer-menu-select] command. +When `outline-minor-mode' is enabled and point is on the outline +heading line, this command will mark all entries in the outline." (interactive nil Buffer-menu-mode) - (tabulated-list-set-col 0 (char-to-string Buffer-menu-marker-char) t) - (forward-line)) + (cond ((tabulated-list-get-id) + (tabulated-list-set-col 0 (char-to-string Buffer-menu-marker-char) t) + (forward-line)) + ((and (bound-and-true-p outline-minor-mode) (outline-on-heading-p)) + (let ((limit (save-excursion (outline-end-of-subtree) (point))) + ;; Skip outline subheadings on recursive calls + (outline-minor-mode nil)) + (forward-line) + (while (< (point) limit) + (Buffer-menu-mark)))) + (t (forward-line)))) (defun Buffer-menu-unmark (&optional backup) "Cancel all requested operations on buffer on this line and move down. -Optional prefix arg means move up." +Optional prefix arg means move up. +When `outline-minor-mode' is enabled and point is on the outline +heading line, this command will unmark all entries in the outline." (interactive "P" Buffer-menu-mode) - (Buffer-menu--unmark) - (forward-line (if backup -1 1))) + (cond ((tabulated-list-get-id) + (Buffer-menu--unmark) + (forward-line (if backup -1 1))) + ((and (bound-and-true-p outline-minor-mode) (outline-on-heading-p)) + (let ((old-pos (point)) + (limit (save-excursion (outline-end-of-subtree) (point))) + ;; Skip outline subheadings on recursive calls + (outline-minor-mode nil)) + (forward-line) + (while (< (point) limit) + (Buffer-menu-unmark)) + (when backup + (goto-char old-pos) + (outline-previous-heading)))) + (t (forward-line (if backup -1 1))))) (defun Buffer-menu-unmark-all-buffers (mark) "Cancel a requested operation on all buffers. @@ -449,7 +480,10 @@ When called interactively prompt for MARK; RET remove all marks." "Move up and cancel all requested operations on buffer on line above." (interactive nil Buffer-menu-mode) (forward-line -1) - (Buffer-menu--unmark)) + (while (and (not (tabulated-list-get-id)) (not (bobp))) + (forward-line -1)) + (unless (bobp) + (Buffer-menu--unmark))) (defun Buffer-menu--unmark () (tabulated-list-set-col 0 " " t) @@ -465,20 +499,34 @@ A subsequent \\\\[Buffer-menu-execute] command \ will delete it. If prefix argument ARG is non-nil, it specifies the number of -buffers to delete; a negative ARG means to delete backwards." +buffers to delete; a negative ARG means to delete backwards. + +When `outline-minor-mode' is enabled and point is on the outline +heading line, this command will mark all entries in the outline. +However, ARG is not supported in this case." (interactive "p" Buffer-menu-mode) - (if (or (null arg) (= arg 0)) - (setq arg 1)) - (while (> arg 0) - (when (Buffer-menu-buffer) - (tabulated-list-set-col 0 (char-to-string Buffer-menu-del-char) t)) - (forward-line 1) - (setq arg (1- arg))) - (while (< arg 0) - (when (Buffer-menu-buffer) - (tabulated-list-set-col 0 (char-to-string Buffer-menu-del-char) t)) - (forward-line -1) - (setq arg (1+ arg)))) + (cond + ((and (bound-and-true-p outline-minor-mode) (outline-on-heading-p)) + (let ((limit (save-excursion (outline-end-of-subtree) (point))) + ;; Skip outline subheadings on recursive calls + (outline-minor-mode nil)) + (forward-line) + (while (< (point) limit) + (Buffer-menu-delete)))) + (t + (if (or (null arg) (= arg 0)) + (setq arg 1)) + (while (> arg 0) + (when (Buffer-menu-buffer) + (tabulated-list-set-col 0 (char-to-string Buffer-menu-del-char) t)) + (forward-line 1) + (setq arg (1- arg))) + + (while (< arg 0) + (when (Buffer-menu-buffer) + (tabulated-list-set-col 0 (char-to-string Buffer-menu-del-char) t)) + (forward-line -1) + (setq arg (1+ arg)))))) (defun Buffer-menu-delete-backwards (&optional arg) "Mark the buffer on this Buffer Menu line for deletion, and move up. @@ -491,11 +539,22 @@ will delete the marked buffer. Prefix ARG (defun Buffer-menu-save () "Mark the buffer on this Buffer Menu line for saving. A subsequent \\\\[Buffer-menu-execute] \ -command will save it." +command will save it. +When `outline-minor-mode' is enabled and point is on the outline +heading line, this command will mark all entries in the outline." (interactive nil Buffer-menu-mode) - (when (Buffer-menu-buffer) - (tabulated-list-set-col 2 "S" t) - (forward-line 1))) + (cond ((tabulated-list-get-id) + (when (Buffer-menu-buffer) + (tabulated-list-set-col 2 "S" t)) + (forward-line)) + ((and (bound-and-true-p outline-minor-mode) (outline-on-heading-p)) + (let ((limit (save-excursion (outline-end-of-subtree) (point))) + ;; Skip outline subheadings on recursive calls + (outline-minor-mode nil)) + (forward-line) + (while (< (point) limit) + (Buffer-menu-save)))) + (t (forward-line)))) (defun Buffer-menu-not-modified (&optional arg) "Mark the buffer on this line as unmodified (no changes to save). commit 7d36bb0547fd2f1e0315edbe579bed68796d5c39 Author: Eli Zaretskii Date: Fri Jun 7 09:11:04 2024 +0300 ; * src/dispnew.c (update_frame_line): Fix thinko (bug#71289). diff --git a/src/dispnew.c b/src/dispnew.c index 8223b90f4a4..e74147f1456 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -5265,7 +5265,7 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p) /* This should never happen, but evidently sometimes does if one resizes the frame quickly enough. Prevent aborts in cmcheckmagic. */ - if (vpos >= FRAME_LINES (f)) + if (vpos >= FRAME_TOTAL_LINES (f)) return; if (colored_spaces_p) commit 6906ed28f1b4ac0cf0a2a725e7402290f33c26e2 Author: João Távora Date: Thu Jun 6 17:08:28 2024 -0500 Eglot: better fix for bug#70724 If the project's root is or destroyed , this may happen for a variety of reasons, including reasons affecting non-reconnection scenarios, so better to check in eglot--connect. An Eglot "reconnection" has always created as accurate a copy of the previous server object as possible, down to the 'eq'ness or the saved initargs, language ids, etc. So re-querying for projects is not the thing to do here. A new different server can be created with `M-x eglot` which will ask about shutting down the existing one. * lisp/progmodes/eglot.el (eglot-reconnect): Revert previous change. (eglot--connect): Do sanity check here diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index f58a895a3f1..03da5c7b22a 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -1419,15 +1419,11 @@ INTERACTIVE is t if called interactively." (interactive (list (eglot--current-server-or-lose) t)) (when (jsonrpc-running-p server) (ignore-errors (eglot-shutdown server interactive nil 'preserve-buffers))) - (let* ((default-directory (project-root (eglot--project server))) - (project (eglot--current-project))) - (if (not project) - (eglot--error "Project in `%s' is gone!" default-directory) - (eglot--connect (eglot--major-modes server) - project - (eieio-object-class-name server) - (eglot--saved-initargs server) - (eglot--language-ids server)))) + (eglot--connect (eglot--major-modes server) + (eglot--project server) + (eieio-object-class-name server) + (eglot--saved-initargs server) + (eglot--language-ids server)) (eglot--message "Reconnected!")) (defvar eglot--managed-mode) ; forward decl @@ -1518,7 +1514,12 @@ Each function is passed the server as an argument") This docstring appeases checkdoc, that's all." (let* ((default-directory (project-root project)) (nickname (project-name project)) - (readable-name (format "EGLOT (%s/%s)" nickname managed-modes)) + (readable-name + (progn + (unless (file-exists-p default-directory) + ;; could happen because of bug#70724 or just because + (eglot--error "Project '%s' is gone!" nickname)) + (format "EGLOT (%s/%s)" nickname managed-modes))) server-info (contact (if (functionp contact) (funcall contact) contact)) (initargs commit b571c6571c8bc4c34569650104aee273c19cbfd4 Author: Dmitry Gutov Date: Thu Jun 6 23:26:25 2024 +0300 eglot-reconnect: Re-fetch the current project * lisp/progmodes/eglot.el (eglot-reconnect): Retrieve the current project just in case something changed (bug#70724). diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 5ccae5210fe..f58a895a3f1 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -1419,11 +1419,15 @@ INTERACTIVE is t if called interactively." (interactive (list (eglot--current-server-or-lose) t)) (when (jsonrpc-running-p server) (ignore-errors (eglot-shutdown server interactive nil 'preserve-buffers))) - (eglot--connect (eglot--major-modes server) - (eglot--project server) - (eieio-object-class-name server) - (eglot--saved-initargs server) - (eglot--language-ids server)) + (let* ((default-directory (project-root (eglot--project server))) + (project (eglot--current-project))) + (if (not project) + (eglot--error "Project in `%s' is gone!" default-directory) + (eglot--connect (eglot--major-modes server) + project + (eieio-object-class-name server) + (eglot--saved-initargs server) + (eglot--language-ids server)))) (eglot--message "Reconnected!")) (defvar eglot--managed-mode) ; forward decl commit 91f51f5ac5e6343359ffcadc8341b8da767aab87 Author: Eli Zaretskii Date: Thu Jun 6 17:43:00 2024 +0300 Prevent another abort in 'cmcheckmagic' * src/dispnew.c (update_frame_line): Prevent rare aborts when TTY frame is resized. (Bug#71289) diff --git a/src/dispnew.c b/src/dispnew.c index a3c5cbbcf00..8223b90f4a4 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -5263,6 +5263,11 @@ update_frame_line (struct frame *f, int vpos, bool updating_menu_p) bool colored_spaces_p = (FACE_FROM_ID (f, DEFAULT_FACE_ID)->background != FACE_TTY_DEFAULT_BG_COLOR); + /* This should never happen, but evidently sometimes does if one + resizes the frame quickly enough. Prevent aborts in cmcheckmagic. */ + if (vpos >= FRAME_LINES (f)) + return; + if (colored_spaces_p) write_spaces_p = 1; commit a48f062e36be3ce5890a8a789272f31f074fea40 Author: Po Lu Date: Thu Jun 6 20:55:40 2024 +0800 Minor enhancements to the Android build system * build-aux/ndk-build-helper-1.mk: * build-aux/ndk-build-helper-2.mk: * cross/ndk-build/ndk-build-shared-library.mk: * cross/ndk-build/ndk-build-static-library.mk: * cross/ndk-build/ndk-resolve.mk (NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE)): (NDK_LOCAL_SO_NAMES_$(LOCAL_MODULE)): (NDK_LOCAL_A_NAMES_$(LOCAL_MODULE)): Reinforce tests for string prefixes. * m4/ndk-build.m4 (ndk_INIT): Guarantee that a module's dependencies are recorded. * configure.ac (XCONFIGURE): Prepare for building librsvg. diff --git a/build-aux/ndk-build-helper-1.mk b/build-aux/ndk-build-helper-1.mk index 490064b6e32..985f7cddfaf 100644 --- a/build-aux/ndk-build-helper-1.mk +++ b/build-aux/ndk-build-helper-1.mk @@ -37,7 +37,7 @@ $(info Building $(build_kind)) $(info $(LOCAL_MODULE)) $(info $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES) $(LOCAL_SRC_FILES$(EMACS_ABI)))) -ifeq ($(findstring lib,$(LOCAL_MODULE)),lib) +ifeq ($(filter-out lib%,$(LOCAL_MODULE)),) NDK_SO_NAMES = $(LOCAL_MODULE)_emacs.so else NDK_SO_NAMES = lib$(LOCAL_MODULE)_emacs.so @@ -50,7 +50,7 @@ $$(foreach module,$$(filter-out $$(SYSTEM_LIBRARIES), $$(NDK_$(1)_STATIC_LIBRARI endef define add-so-name -ifeq ($(findstring lib,$(1)),lib) +ifeq ($(filter-out lib%,$(1)),) NDK_SO_NAME = $(1)_emacs.so else NDK_SO_NAME = lib$(1)_emacs.so diff --git a/build-aux/ndk-build-helper-2.mk b/build-aux/ndk-build-helper-2.mk index e696fcbdade..697740b3d45 100644 --- a/build-aux/ndk-build-helper-2.mk +++ b/build-aux/ndk-build-helper-2.mk @@ -31,14 +31,14 @@ $(info Building $(build_kind)) $(info $(LOCAL_MODULE)) $(info $(addprefix $(LOCAL_PATH)/,$(LOCAL_SRC_FILES) $(LOCAL_SRC_FILES$(EMACS_ABI)))) -ifeq ($(findstring lib,$(LOCAL_MODULE)),lib) +ifeq ($(filter-out lib%,$(LOCAL_MODULE)),) NDK_A_NAMES = $(LOCAL_MODULE).a else NDK_A_NAMES = lib$(LOCAL_MODULE).a endif define add-a-name -ifeq ($(findstring lib,$(1)),lib) +ifeq ($(filter-out lib%,$(1)),) NDK_A_NAME = $(1).a else NDK_A_NAME = lib$(1).a @@ -58,7 +58,7 @@ endif endef define add-so-name -ifeq ($(findstring lib,$(1)),lib) +ifeq ($(filter-out lib%,$(1)),) NDK_SO_NAME = $(1)_emacs.so else NDK_SO_NAME = lib$(1)_emacs.so diff --git a/configure.ac b/configure.ac index e3213f4ac79..1754ca4f977 100644 --- a/configure.ac +++ b/configure.ac @@ -1251,6 +1251,7 @@ package will likely install on older systems but crash on startup.]) passthrough="$passthrough --with-pop=$with_pop" passthrough="$passthrough --with-harfbuzz=$with_harfbuzz" passthrough="$passthrough --with-threads=$with_threads" + passthrough="$passthrough --with-rsvg=$with_rsvg" # Now pass through some checking-related options. emacs_val="--enable-check-lisp-object-type=$enable_check_lisp_object_type" @@ -1341,9 +1342,9 @@ if test "$ANDROID" = "yes"; then with_harfbuzz=no with_native_compilation=no with_threads=no + with_rsvg=no fi - with_rsvg=no with_libsystemd=no with_cairo=no with_xft=no @@ -3559,10 +3560,13 @@ fi HAVE_RSVG=no if test "${HAVE_X11}" = "yes" || test "${HAVE_NS}" = "yes" \ || test "${opsys}" = "mingw32" || test "${HAVE_BE_APP}" = "yes" \ - || test "${window_system}" = "pgtk"; then + || test "${window_system}" = "pgtk" \ + || test "${REALLY_ANDROID}" = "yes"; then if test "${with_rsvg}" != "no"; then RSVG_REQUIRED=2.14.0 - RSVG_MODULE="librsvg-2.0 >= $RSVG_REQUIRED" + AS_IF([test "${REALLY_ANDROID}" = "yes"], + [RSVG_MODULE="librsvg"], + [RSVG_MODULE="librsvg-2.0 >= $RSVG_REQUIRED"]) EMACS_CHECK_MODULES([RSVG], [$RSVG_MODULE]) AC_SUBST([RSVG_CFLAGS]) diff --git a/cross/ndk-build/ndk-build-shared-library.mk b/cross/ndk-build/ndk-build-shared-library.mk index 74c6756a0c1..b0605503271 100644 --- a/cross/ndk-build/ndk-build-shared-library.mk +++ b/cross/ndk-build/ndk-build-shared-library.mk @@ -125,7 +125,7 @@ NDK_CFLAGS ::= -mthumb endif endif -ifeq ($(findstring lib,$(LOCAL_MODULE)),lib) +ifeq ($(filter-out lib%,$(LOCAL_MODULE)),) LOCAL_MODULE_FILENAME := $(LOCAL_MODULE)_emacs else LOCAL_MODULE_FILENAME := lib$(LOCAL_MODULE)_emacs diff --git a/cross/ndk-build/ndk-build-static-library.mk b/cross/ndk-build/ndk-build-static-library.mk index aba4539f6bb..449eaadb403 100644 --- a/cross/ndk-build/ndk-build-static-library.mk +++ b/cross/ndk-build/ndk-build-static-library.mk @@ -110,7 +110,7 @@ NDK_CFLAGS ::= -mthumb endif endif -ifeq ($(findstring lib,$(LOCAL_MODULE)),lib) +ifeq ($(filter-out lib%,$(LOCAL_MODULE)),) LOCAL_MODULE_FILENAME := $(LOCAL_MODULE) else LOCAL_MODULE_FILENAME := lib$(LOCAL_MODULE) diff --git a/cross/ndk-build/ndk-resolve.mk b/cross/ndk-build/ndk-resolve.mk index 4d8ecf8667a..896c29f7f90 100644 --- a/cross/ndk-build/ndk-resolve.mk +++ b/cross/ndk-build/ndk-resolve.mk @@ -140,7 +140,7 @@ NDK_SO_EXTRA_FLAGS_$(LOCAL_MODULE) += -landroid endif ifeq ($(findstring $(1),$(NDK_SYSTEM_LIBRARIES))$(2)$(3),) -ifneq ($(findstring lib,$(1)),) +ifeq ($(filter-out lib%,$(1)),) NDK_LOCAL_SO_NAMES_$(LOCAL_MODULE) += $(1)_emacs.so else NDK_LOCAL_SO_NAMES_$(LOCAL_MODULE) += lib$(1)_emacs.so @@ -148,7 +148,7 @@ endif endif ifneq ($(2),) -ifneq ($(findstring lib,$(1)),) +ifeq ($(filter-out lib%,$(1)),) NDK_LOCAL_A_NAMES_$(LOCAL_MODULE) += $(1).a else NDK_LOCAL_A_NAMES_$(LOCAL_MODULE) += lib$(1).a @@ -156,7 +156,7 @@ endif endif ifneq ($(3),) -ifneq ($(findstring lib,$(1)),) +ifeq ($(filter-out lib%,$(1)),) NDK_WHOLE_A_NAMES_$(LOCAL_MODULE) += $(1).a else NDK_WHOLE_A_NAMES_$(LOCAL_MODULE) += lib$(1).a diff --git a/m4/ndk-build.m4 b/m4/ndk-build.m4 index 2689ee34287..f86d4e4fc1e 100644 --- a/m4/ndk-build.m4 +++ b/m4/ndk-build.m4 @@ -178,6 +178,7 @@ but a working C++ compiler was not found.])]) AC_MSG_RESULT([yes]) # Make sure the module is prepended. + ndk_MODULES="$ndk_MODULES $module_target" ndk_MAKEFILES="$ndk_android_mk $ndk_MAKEFILES" ndk_import_includes="$module_includes $ndk_import_includes" commit c86995d07e98e6f1a48f8df791aa4164316159d9 Author: Kyle Meyer Date: Wed May 29 00:05:46 2024 -0400 Enable code block evaluation when generating .org manuals * doc/misc/Makefile.in ($(1:.org=.texi)): Enable code block evaluation in Org mode manual and other .org manuals to produce automatically generated parts. (Bug#71394) When testing a scratch sync to the Emacs repo, the build failed with make[3]: Leaving directory '/home/kyle/src/savannah/emacs--master/lisp' Evaluate this emacs-lisp code block on your system? (yes or no) Error: end-of-file ("Error reading from stdin") yes-or-no-p("Evaluate this emacs-lisp code block on your system? ") That's expected given 715148131 (org-manual: Automatically generate export option list, 2023-07-31) and the default org-confirm-babel-evaluate value. diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in index 2841916dc89..b26d3525a22 100644 --- a/doc/misc/Makefile.in +++ b/doc/misc/Makefile.in @@ -250,6 +250,7 @@ define org_template $(1:.org=.texi): $(1) ${top_srcdir}/lisp/org/ox-texinfo.el $${AM_V_GEN}cd "$${srcdir}" && $${emacs} -l ox-texinfo \ --eval '(setq gc-cons-threshold 50000000)' \ + --eval '(setq org-confirm-babel-evaluate nil)' \ -f org-texinfo-export-to-texinfo-batch $$(notdir $$<) $$(notdir $$@) endef commit 9da2faf73b7f2e773dfb778e49ed90e58a852e43 Author: Eli Zaretskii Date: Thu Jun 6 13:06:58 2024 +0300 ; Fix last change in sqlite.c * etc/NEWS: * doc/lispref/text.texi (Database): * src/sqlite.c (Fsqlite_execute_batch): Fix last change (Bug#70145). diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 7f2123d06f9..41ab90a80f3 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -5417,8 +5417,8 @@ called @var{gif}, you have to mark it specially to let @defun sqlite-execute-batch db statements Execute the @acronym{SQL} @var{statements}. @var{statements} is a string containing 0 or more @acronym{SQL} statements. This command -might be useful when we want to execute multiple @acronym{DDL} -statements. +might be useful when a Lisp program needs to execute multiple Data +Definition Language (@acronym{DDL}) statements in one go. @end defun diff --git a/etc/NEWS b/etc/NEWS index b53136e3ba2..808cd0562db 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -485,10 +485,10 @@ its shebang line, Emacs will now skip over 'env -S' and deduce the major mode based on the interpreter after 'env -S'. +++ -** New command 'sqlite-execute-batch'. -This command lets the user execute multiple SQL commands in one -command. It is useful when the user wants to evaluate an entire SQL -file. +** New function 'sqlite-execute-batch'. +This function lets the user execute multiple SQL statements in one go. +It is useful, for example, when a Lisp program needs to evaluate an +entire SQL file. +++ diff --git a/src/sqlite.c b/src/sqlite.c index c606fa5f831..53f9d095114 100644 --- a/src/sqlite.c +++ b/src/sqlite.c @@ -647,13 +647,13 @@ sqlite_exec (sqlite3 *sdb, const char *query) } DEFUN ("sqlite-execute-batch", Fsqlite_execute_batch, Ssqlite_execute_batch, 2, 2, 0, - doc: /* Execute multiple SQL statements in DB. -Query is a string containing 0 or more SQL statements. */) - (Lisp_Object db, Lisp_Object query) + doc: /* Execute multiple SQL STATEMENTS in DB. +STATEMENTS is a string containing 0 or more SQL statements. */) + (Lisp_Object db, Lisp_Object statements) { check_sqlite (db, false); - CHECK_STRING (query); - Lisp_Object encoded = encode_string(query); + CHECK_STRING (statements); + Lisp_Object encoded = encode_string (statements); return sqlite_exec (XSQLITE (db)->db, SSDATA (encoded)); } commit 7ba4de0077c5dee43bd83b134c459127855cd8cc Merge: 23ef989935d 32bfc825a7e Author: Eli Zaretskii Date: Thu Jun 6 13:06:51 2024 +0300 Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs commit 23ef989935d38fe5c2c105933ae5f4d692656c72 Author: Javier Olaechea Date: Sun Mar 31 23:07:10 2024 -0500 Add 'sqlite-execute-batch' command This command is similar to 'sqlite-execute' except that it executes multiple statements in exchange for not accepting any arguments. (Bug#70145) * src/sqlite.c (Fsqlite_execute_batch): New function. * test/src/sqlite-tests.el (sqlite-multiple-statements): Add smoke test for 'sqlite-execute-batch'. * etc/NEWS: Mention new command 'sqlite-execute-batch'. * doc/lispref/text.texi (Database): Document the new command. diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 07fb730f0f1..7f2123d06f9 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -5414,6 +5414,14 @@ called @var{gif}, you have to mark it specially to let @end defun +@defun sqlite-execute-batch db statements +Execute the @acronym{SQL} @var{statements}. @var{statements} is a +string containing 0 or more @acronym{SQL} statements. This command +might be useful when we want to execute multiple @acronym{DDL} +statements. + +@end defun + @defun sqlite-select db query &optional values return-type Select some data from @var{db} and return them. For instance: diff --git a/etc/NEWS b/etc/NEWS index 922721f143c..b53136e3ba2 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -484,6 +484,13 @@ When visiting a script that invokes 'env -S INTERPRETER ARGS...' in its shebang line, Emacs will now skip over 'env -S' and deduce the major mode based on the interpreter after 'env -S'. ++++ +** New command 'sqlite-execute-batch'. +This command lets the user execute multiple SQL commands in one +command. It is useful when the user wants to evaluate an entire SQL +file. + ++++ * Editing Changes in Emacs 30.1 diff --git a/src/sqlite.c b/src/sqlite.c index 261080da673..c606fa5f831 100644 --- a/src/sqlite.c +++ b/src/sqlite.c @@ -646,6 +646,17 @@ sqlite_exec (sqlite3 *sdb, const char *query) return Qt; } +DEFUN ("sqlite-execute-batch", Fsqlite_execute_batch, Ssqlite_execute_batch, 2, 2, 0, + doc: /* Execute multiple SQL statements in DB. +Query is a string containing 0 or more SQL statements. */) + (Lisp_Object db, Lisp_Object query) +{ + check_sqlite (db, false); + CHECK_STRING (query); + Lisp_Object encoded = encode_string(query); + return sqlite_exec (XSQLITE (db)->db, SSDATA (encoded)); +} + DEFUN ("sqlite-transaction", Fsqlite_transaction, Ssqlite_transaction, 1, 1, 0, doc: /* Start a transaction in DB. */) (Lisp_Object db) @@ -866,6 +877,7 @@ syms_of_sqlite (void) defsubr (&Ssqlite_close); defsubr (&Ssqlite_execute); defsubr (&Ssqlite_select); + defsubr (&Ssqlite_execute_batch); defsubr (&Ssqlite_transaction); defsubr (&Ssqlite_commit); defsubr (&Ssqlite_rollback); diff --git a/test/src/sqlite-tests.el b/test/src/sqlite-tests.el index a10dca9a0c9..e87a5fc77b1 100644 --- a/test/src/sqlite-tests.el +++ b/test/src/sqlite-tests.el @@ -261,4 +261,30 @@ '("Joe" "Doe")) '((1 "Joe"))))))) +(ert-deftest sqlite-multiple-statements () + (skip-unless (sqlite-available-p)) + (let ((db (sqlite-open nil)) + (query (with-temp-buffer + (insert "-- -*- sql-product: sqlite -*- + +-- I 💘 emojis + +CREATE TABLE settings ( + name TEXT NOT NULL, + value TEXT, + section TEXT NOT NULL, + PRIMARY KEY (section, name) +); + +CREATE TABLE tags📎 ( + name TEXT PRIMARY KEY NOT NULL +); + +-- CREATE TABLE todo_states (id INTEGER PRIMARY KEY, name TEXT NOT NULL); +") + (buffer-string)))) + (sqlite-execute-batch db query) + (should (equal '(("settings") ("tags📎")) + (sqlite-select db "select name from sqlite_master where type = 'table' and name not like 'sqlite_%' order by name"))))) + ;;; sqlite-tests.el ends here commit 32bfc825a7e4848f2bf28987ab5259d4031ff6aa Author: Mattias Engdegård Date: Wed Jun 5 18:28:59 2024 +0200 Format string warnings for more functions (bug#71379) * lisp/emacs-lisp/bytecomp.el (byte-compile-format-like): Add message-box, message-or-box, warn and user-error. diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 03cfbe6f4c9..d59e89bd7de 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -1643,7 +1643,8 @@ extra args." nargs (if (= nargs 1) "" "s") nfields (if (= nfields 1) "" "s")))))) -(dolist (elt '(format message format-message error)) +(dolist (elt '( format message format-message message-box message-or-box + warn error user-error)) (put elt 'byte-compile-format-like t)) ;; Warn if the function or macro is being redefined with a different commit 7fbafb9d9527f3888469dead8309fd748d2fb9e0 Author: Eli Zaretskii Date: Thu Jun 6 10:47:21 2024 +0300 Attempt to fix rare assertion violations in 'mark_terminals' * src/terminal.c (delete_terminal): Block input while we modify the frame list and 'terminal_list'. (Bug#71289) diff --git a/src/terminal.c b/src/terminal.c index e8316ba32e8..5c21341d905 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -22,6 +22,7 @@ along with GNU Emacs. If not, see . */ #include "character.h" #include "frame.h" #include "termchar.h" +#include "blockinput.h" #include "termhooks.h" #include "keyboard.h" @@ -316,6 +317,9 @@ delete_terminal (struct terminal *terminal) delete_terminal_hook when we delete our last frame. */ if (!terminal->name) return; + + /* Protection while we are in inconsistent state. */ + block_input (); xfree (terminal->name); terminal->name = NULL; @@ -331,6 +335,7 @@ delete_terminal (struct terminal *terminal) } delete_terminal_internal (terminal); + unblock_input (); } void