From 3bc5efb87e5ac9b7068e71307466b2d0220e92fb Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 18 May 2023 17:20:36 +0300 Subject: [PATCH 01/54] ; * lisp/emacs-lisp/benchmark.el (benchmark-progn): Fix declare form. --- lisp/emacs-lisp/benchmark.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/emacs-lisp/benchmark.el b/lisp/emacs-lisp/benchmark.el index dc7889c40a0..e50b8524f29 100644 --- a/lisp/emacs-lisp/benchmark.el +++ b/lisp/emacs-lisp/benchmark.el @@ -152,7 +152,7 @@ to call it without any argument." (defmacro benchmark-progn (&rest body) "Evaluate BODY and message the time taken. The return value is the value of the final form in BODY." - (declare (debug body) (indent 0)) + (declare (debug t) (indent 0)) (let ((value (make-symbol "value")) (start (make-symbol "start")) (gcs (make-symbol "gcs")) From 459d08c7fe7f723b3cefe71fa50bbe4481f66995 Mon Sep 17 00:00:00 2001 From: Yuan Fu Date: Thu, 18 May 2023 14:44:26 -0700 Subject: [PATCH 02/54] Fix tree-sitter test (bug#63481) * test/src/treesit-tests.el (treesit-basic-parsing): Latest json parser doesn't return an error on empty buffer or multiple objects anymore [1]. https://github.com/tree-sitter/tree-sitter-json/commit/40a81c01a40ac48744e0c8ccabbaba1920441199 --- test/src/treesit-tests.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/src/treesit-tests.el b/test/src/treesit-tests.el index 468cd221ef9..fef603840f9 100644 --- a/test/src/treesit-tests.el +++ b/test/src/treesit-tests.el @@ -66,7 +66,7 @@ (should (equal (treesit-node-string (treesit-parser-root-node parser)) - "(ERROR)")) + "(document)")) (insert "[1,2,3]") (should From 8e61d23f71e75225e1e48a572db76c2845a4201a Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Fri, 19 May 2023 21:04:50 +0300 Subject: [PATCH 03/54] Split windows horizontally in places that use split to create a new window. * lisp/tab-bar.el (tab-bar-new-tab-to): * lisp/window.el (window-state-put): To create a new window, split horizontally instead of vertically. Use 'window-safe-min-width' for the SIZE arg of 'split-window'. (bug#62592) --- lisp/tab-bar.el | 3 ++- lisp/window.el | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index ab428b81631..73f2ff77c50 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -1568,7 +1568,8 @@ After the tab is created, the hooks in (window-state-put (window-state-get))) ;; Create a new window to get rid of old window parameters ;; (e.g. prev/next buffers) of old window. - (split-window) (delete-window)))) + (split-window nil window-safe-min-width t) + (delete-window)))) (let ((buffer (if (and (functionp tab-bar-new-tab-choice) diff --git a/lisp/window.el b/lisp/window.el index 016d53ffbdd..a11b1a51f8f 100644 --- a/lisp/window.el +++ b/lisp/window.el @@ -6382,7 +6382,7 @@ windows can get as small as `window-safe-min-height' and (selected-window))) (delete-other-windows-internal window root) ;; Create a new window to replace the existing one. - (setq window (prog1 (split-window window) + (setq window (prog1 (split-window window window-safe-min-width t) (delete-window window))))) (set-window-dedicated-p window nil) From 42a28ffdc27498b66904c3d49e2f000a9b4690ca Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Fri, 19 May 2023 21:14:16 +0300 Subject: [PATCH 04/54] * lisp/tab-bar.el: Don't use 'minibuffer-selected-window' (bug#62427). (tab-bar-select-tab, tab-bar-new-tab-to): Use 'window-minibuffer-p' instead of 'minibuffer-selected-window'. And switch to 'get-mru-window' instead of 'minibuffer-selected-window'. --- lisp/tab-bar.el | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 73f2ff77c50..dc9ea63c490 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -1319,8 +1319,8 @@ Negative TAB-NUMBER counts tabs from the end of the tab bar." (ws ;; `window-state-put' fails when called in the minibuffer - (when (minibuffer-selected-window) - (select-window (minibuffer-selected-window))) + (when (window-minibuffer-p) + (select-window (get-mru-window))) (window-state-put ws nil 'safe))) ;; Select the minibuffer when it was active before switching tabs @@ -1331,8 +1331,8 @@ Negative TAB-NUMBER counts tabs from the end of the tab bar." ;; another tab, then after going back to the first tab, it has ;; such inconsistent state that the current buffer is the minibuffer, ;; but its window is not active. So try to undo this mess. - (when (and (minibufferp) (not (active-minibuffer-window))) - (other-window 1)) + (when (and (window-minibuffer-p) (not (active-minibuffer-window))) + (select-window (get-mru-window))) (when tab-bar-history-mode (setq tab-bar-history-omit t)) @@ -1550,8 +1550,8 @@ After the tab is created, the hooks in (when tab-bar-new-tab-choice ;; Handle the case when it's called in the active minibuffer. - (when (minibuffer-selected-window) - (select-window (minibuffer-selected-window))) + (when (window-minibuffer-p) + (select-window (get-mru-window))) (let ((ignore-window-parameters t) (window--sides-inhibit-check t)) (if (eq tab-bar-new-tab-choice 'clone) From f571e8f1bb678c52839180e450c2415b31a70516 Mon Sep 17 00:00:00 2001 From: Yuan Fu Date: Fri, 19 May 2023 16:09:17 -0700 Subject: [PATCH 05/54] Improve c-ts-mode font-lock for function names (bug#63390) When a function definition has preproc directives in its body, it can't correctly parse into a function_definition. This fix tries to recognize this case and highlight the function_declarator correctly. * lisp/progmodes/c-ts-mode.el: (c-ts-mode--font-lock-settings): New rule. (c-ts-mode--top-level-declarator): New function. --- lisp/progmodes/c-ts-mode.el | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index b042782efa7..7a57d5adeb1 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -627,6 +627,13 @@ MODE is either `c' or `cpp'." (function_definition declarator: (_) @c-ts-mode--fontify-declarator) + ;; When a function definition has preproc directives in its body, + ;; it can't correctly parse into a function_definition. We still + ;; want to highlight the function_declarator correctly, hence + ;; this rule. See bug#63390 for more detail. + ((function_declarator) @c-ts-mode--fontify-declarator + (:pred c-ts-mode--top-level-declarator + @c-ts-mode--fontify-declarator)) (parameter_declaration declarator: (_) @c-ts-mode--fontify-declarator) @@ -750,6 +757,19 @@ For NODE, OVERRIDE, START, END, and ARGS, see (treesit-node-start identifier) (treesit-node-end identifier) face override start end)))) +(defun c-ts-mode--top-level-declarator (node) + "Return non-nil if NODE is a top-level function_declarator." + ;; These criterion are observed in + ;; xterm.c:x_draw_glyphless_glyph_string_foreground on emacs-29 + ;; branch, described in bug#63390. They might not cover all cases + ;; where a function_declarator is at top-level, outside of a + ;; function_definition. We might need to amend them as we discover + ;; more cases. + (let* ((parent (treesit-node-parent node)) + (grandparent (treesit-node-parent parent))) + (and (treesit-node-match-p parent "ERROR") + (null grandparent)))) + (defun c-ts-mode--fontify-variable (node override start end &rest _) "Fontify an identifier node if it is a variable. Don't fontify if it is a function identifier. For NODE, From cec9333dc5292f9aca2642209617310a64570763 Mon Sep 17 00:00:00 2001 From: Yuan Fu Date: Sat, 20 May 2023 00:45:39 -0700 Subject: [PATCH 06/54] Fix c-ts-mode--top-level-declarator * lisp/progmodes/c-ts-mode.el: (c-ts-mode--top-level-declarator): Don't use treesit-node-match-p. --- lisp/progmodes/c-ts-mode.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 7a57d5adeb1..c6cb9520e58 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -767,7 +767,7 @@ For NODE, OVERRIDE, START, END, and ARGS, see ;; more cases. (let* ((parent (treesit-node-parent node)) (grandparent (treesit-node-parent parent))) - (and (treesit-node-match-p parent "ERROR") + (and (equal (treesit-node-type parent) "ERROR") (null grandparent)))) (defun c-ts-mode--fontify-variable (node override start end &rest _) From f49fe936abd48f7458596893d25e3300f59508be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= Date: Sat, 20 May 2023 10:50:25 +0200 Subject: [PATCH 07/54] * etc/NEWS: Note dotimes loop variable scoping change (bug#63586) --- etc/NEWS | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/etc/NEWS b/etc/NEWS index fa428d9c790..cdad1796e77 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -3871,6 +3871,19 @@ The following generalized variables have been made obsolete: 'standard-case-table', 'syntax-table', 'visited-file-modtime', 'window-height', 'window-width', and 'x-get-secondary-selection'. +--- +** The 'dotimes' loop variable can no longer be manipulated in loop body +Previously, the 'dotimes' loop counter could be modified inside the +loop body, but only in code using dynamic binding. Now the behaviour +is the same as when using lexical binding: changes to the loop +variable has no effect on subsequent iterations. That is, + + (dotimes (i 10) + (print i) + (setq i (+ i 6))) + +now always prints the numbers 0 .. 9. + * Lisp Changes in Emacs 29.1 From a6bddd176582f8bea79ec77e1e27bb583a6ef0b5 Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Sat, 20 May 2023 14:00:56 +0200 Subject: [PATCH 08/54] ; * etc/NEWS: Fix typos. --- etc/NEWS | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index cdad1796e77..379ddbde072 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1844,10 +1844,10 @@ this includes "binary" buffers like 'archive-mode' and 'image-mode'. +++ *** New command 'package-upgrade'. -This command allows you to upgrade packages without using 'M-x -list-packages'. A package that comes with the Emacs distribution can -only be upgraded after you install, once, a newer version from ELPA -via the package-menu displayed by 'list-packages'. +This command allows you to upgrade packages without using 'list-packages'. +A package that comes with the Emacs distribution can only be upgraded +after you install, once, a newer version from ELPA via the +package-menu displayed by 'list-packages'. +++ *** New command 'package-upgrade-all'. @@ -1908,10 +1908,10 @@ enabled. In addition, when this option is non-nil, built-in packages for which a new version is available in archives can be upgraded via the package -menu produced by 'M-x list-packages'. If you do set this option -non-nil, we recommend not to use the 'U' command, but instead to use -'/ u' to show the packages which can be upgraded, and then decide -which ones of them you actually want to update from the archives. +menu produced by 'list-packages'. If you do set this option non-nil, +we recommend not to use the 'U' command, but instead to use '/ u' to +show the packages which can be upgraded, and then decide which ones of +them you actually want to update from the archives. If you customize this option, we recommend you place its non-default setting in your early-init file. @@ -3872,11 +3872,11 @@ The following generalized variables have been made obsolete: 'window-height', 'window-width', and 'x-get-secondary-selection'. --- -** The 'dotimes' loop variable can no longer be manipulated in loop body +** The 'dotimes' loop variable can no longer be manipulated in loop body. Previously, the 'dotimes' loop counter could be modified inside the -loop body, but only in code using dynamic binding. Now the behaviour +loop body, but only in code using dynamic binding. Now the behavior is the same as when using lexical binding: changes to the loop -variable has no effect on subsequent iterations. That is, +variable have no effect on subsequent iterations. That is, (dotimes (i 10) (print i) From ead3a2abbfc347b0f562c1e051b370a0617ee8aa Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 20 May 2023 15:43:44 +0300 Subject: [PATCH 09/54] Fix loading SQLite extensions * src/sqlite.c (sqlite3_db_config) [WINDOWSNT]: Load from the DLL. (Fsqlite_load_extension): Use 'sqlite3_db_config' to enable and disable loading of extensions. Add a few free extensions to the allow-list. Fix testing for the ".dll" extension. (Bug#63590) * test/src/sqlite-tests.el (sqlite-load-extension): Fix the test to require successful load if the extension does exist. --- src/sqlite.c | 53 +++++++++++++++++++++++++++++++++------- test/src/sqlite-tests.el | 23 ++++++++++------- 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/src/sqlite.c b/src/sqlite.c index 0361514766a..77ce61ba657 100644 --- a/src/sqlite.c +++ b/src/sqlite.c @@ -23,6 +23,8 @@ YOSHIDA , which can be found at: https://github.com/syohex/emacs-sqlite3 */ #include + +#include #include "lisp.h" #include "coding.h" @@ -80,6 +82,9 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_load_extension, (sqlite3*, const char*, const char*, char**)); # undef sqlite3_load_extension # define sqlite3_load_extension fn_sqlite3_load_extension +DEF_DLL_FN (SQLITE_API int, sqlite3_db_config, (sqlite3*, int, ...)); +# undef sqlite3_db_config +# define sqlite3_db_config fn_sqlite3_db_config # endif # undef sqlite3_finalize @@ -172,6 +177,7 @@ load_dll_functions (HMODULE library) LOAD_DLL_FN (library, sqlite3_exec); # ifdef HAVE_SQLITE3_LOAD_EXTENSION LOAD_DLL_FN (library, sqlite3_load_extension); + LOAD_DLL_FN (library, sqlite3_db_config); # endif LOAD_DLL_FN (library, sqlite3_prepare_v2); return true; @@ -684,9 +690,28 @@ Only modules on Emacs' list of allowed modules can be loaded. */) CHECK_STRING (module); /* Add names of useful and free modules here. */ - const char *allowlist[3] = { "pcre", "csvtable", NULL }; + const char *allowlist[] = { + "base64", + "cksumvfs", + "compress", + "csv", + "csvtable", + "fts3", + "icu", + "pcre", + "percentile", + "regexp", + "rot13", + "rtree", + "sha1", + "uuid", + "vfslog", + "zipfile", + NULL + }; char *name = SSDATA (Ffile_name_nondirectory (module)); - /* Possibly skip past a common prefix. */ + /* Possibly skip past a common prefix (libsqlite3_mod_ is used by + Debian, see https://packages.debian.org/source/sid/sqliteodbc). */ const char *prefix = "libsqlite3_mod_"; if (!strncmp (name, prefix, strlen (prefix))) name += strlen (prefix); @@ -697,7 +722,7 @@ Only modules on Emacs' list of allowed modules can be loaded. */) if (strlen (*allow) < strlen (name) && !strncmp (*allow, name, strlen (*allow)) && (!strcmp (name + strlen (*allow), ".so") - || !strcmp (name + strlen (*allow), ".DLL"))) + || !strcasecmp (name + strlen (*allow), ".dll"))) { do_allow = true; break; @@ -707,12 +732,22 @@ Only modules on Emacs' list of allowed modules can be loaded. */) if (!do_allow) xsignal1 (Qsqlite_error, build_string ("Module name not on allowlist")); - int result = sqlite3_load_extension - (XSQLITE (db)->db, - SSDATA (ENCODE_FILE (Fexpand_file_name (module, Qnil))), - NULL, NULL); - if (result == SQLITE_OK) - return Qt; + /* Expand all Lisp data explicitly, so as to avoid signaling an + error while extension loading is enabled -- we don't want to + "leak" this outside this function. */ + sqlite3 *sdb = XSQLITE (db)->db; + char *ext_fn = SSDATA (ENCODE_FILE (Fexpand_file_name (module, Qnil))); + /* Temporarily enable loading extensions via the C API. */ + int result = sqlite3_db_config (sdb, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, + NULL); + if (result == SQLITE_OK) + { + result = sqlite3_load_extension (sdb, ext_fn, NULL, NULL); + /* Disable loading extensions via C API. */ + sqlite3_db_config (sdb, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 0, NULL); + if (result == SQLITE_OK) + return Qt; + } return Qnil; } #endif /* HAVE_SQLITE3_LOAD_EXTENSION */ diff --git a/test/src/sqlite-tests.el b/test/src/sqlite-tests.el index 460651def78..f7144c15887 100644 --- a/test/src/sqlite-tests.el +++ b/test/src/sqlite-tests.el @@ -197,10 +197,13 @@ (sqlite-load-extension db "/usr/lib/sqlite3/")) (should-error (sqlite-load-extension db "/usr/lib/sqlite3")) - (should - (memq - (sqlite-load-extension db "/usr/lib/sqlite3/pcre.so") - '(nil t))) + (if (eq system-type 'windows-nt) + (should + (eq (sqlite-load-extension db "/usr/lib/sqlite3/pcre.dll") + (file-readable-p "/usr/lib/sqlite3/pcre.dll"))) + (should + (eq (sqlite-load-extension db "/usr/lib/sqlite3/pcre.so") + (file-readable-p "/usr/lib/sqlite3/pcre.so")))) (should-error (sqlite-load-extension @@ -211,11 +214,13 @@ (should-error (sqlite-load-extension db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable")) - (should - (memq - (sqlite-load-extension - db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable.so") - '(nil t))))) + (if (eq system-type 'windows-nt) + (should + (eq (sqlite-load-extension db "/usr/lib/sqlite3/csvtable.dll") + (file-readable-p "/usr/lib/sqlite3/csvtable.dll"))) + (should + (eq (sqlite-load-extension db "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable.so") + (file-readable-p "/usr/lib/x86_64-linux-gnu/libsqlite3_mod_csvtable.so")))))) (ert-deftest sqlite-blob () (skip-unless (sqlite-available-p)) From cf403628692392bde0a00d9d8db6c13544f68441 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 20 May 2023 15:53:21 +0300 Subject: [PATCH 10/54] ; * etc/NEWS: PGTK cannot switch to -new automatically (bug#6355). --- etc/NEWS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/etc/NEWS b/etc/NEWS index 379ddbde072..8bd8c5714c0 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -139,6 +139,11 @@ known to have problems, such as undesirable frame positioning and various issues with keyboard input of sequences such as 'C-;' and 'C-S-u'. +Note that, unlike the X build of Emacs, the PGTK build cannot +automatically switch to text-mode interface (thus emulating -nw) if it +cannot determine the default display; it will instead complain and ask +you to invoke it with the explicit -nw option. + --- ** Emacs no longer reduces the size of the Japanese dictionary. Building Emacs includes generation of a Japanese dictionary, which is From 58eb38cfb47b9802581ff55117510186bcc53b67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= Date: Sat, 20 May 2023 15:04:06 +0200 Subject: [PATCH 11/54] ; * etc/NEWS: missing definite article --- etc/NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/NEWS b/etc/NEWS index 8bd8c5714c0..ad6dffae844 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -3877,7 +3877,7 @@ The following generalized variables have been made obsolete: 'window-height', 'window-width', and 'x-get-secondary-selection'. --- -** The 'dotimes' loop variable can no longer be manipulated in loop body. +** The 'dotimes' loop variable can no longer be manipulated in the loop body. Previously, the 'dotimes' loop counter could be modified inside the loop body, but only in code using dynamic binding. Now the behavior is the same as when using lexical binding: changes to the loop From 8c56557cd9dff754b7f28f5fb919ca3b2c58ebf3 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 20 May 2023 17:56:40 +0300 Subject: [PATCH 12/54] Fix Skeletons menu-bar menu in Python modes * lisp/progmodes/python.el (python-mode, python-ts-mode): Call 'python-skeleton-add-menu-items' here, not in 'python-base-mode', since the "Python" menu is not yet set up in the latter. (Bug#63598) --- lisp/progmodes/python.el | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index f810f1e2164..6fc05b246a6 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -6694,8 +6694,6 @@ implementations: `python-mode' and `python-ts-mode'." (setq-local prettify-symbols-alist python-prettify-symbols-alist) - (python-skeleton-add-menu-items) - (make-local-variable 'python-shell-internal-buffer) (add-hook 'flymake-diagnostic-functions #'python-flymake nil t)) @@ -6719,6 +6717,8 @@ implementations: `python-mode' and `python-ts-mode'." (add-hook 'which-func-functions #'python-info-current-defun nil t) + (python-skeleton-add-menu-items) + (when python-indent-guess-indent-offset (python-indent-guess-indent-offset))) @@ -6745,6 +6745,8 @@ implementations: `python-mode' and `python-ts-mode'." #'python--treesit-defun-name) (treesit-major-mode-setup) + (python-skeleton-add-menu-items) + (when python-indent-guess-indent-offset (python-indent-guess-indent-offset)) From 6b60c8142ea10b774cd01db39f803f806df5fc5b Mon Sep 17 00:00:00 2001 From: Liu Hui Date: Wed, 17 May 2023 16:39:18 +0800 Subject: [PATCH 13/54] Fix systemd unit completion for old versions of systemd * lisp/pcmpl-linux.el (pcmpl-linux--systemd-units): Use '--no-legend' for compatibility with older versions of systemctl. (Bug#63411) --- lisp/pcmpl-linux.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/pcmpl-linux.el b/lisp/pcmpl-linux.el index 082072d87d2..589b4799c8d 100644 --- a/lisp/pcmpl-linux.el +++ b/lisp/pcmpl-linux.el @@ -119,7 +119,8 @@ Test is done using `equal'." (with-temp-buffer (apply #'call-process "systemctl" nil '(t nil) nil - "list-units" "--full" "--legend=no" "--plain" args) + ;; "--legend=no" doesn't exist before systemd v248 + "list-units" "--full" "--no-legend" "--plain" args) (goto-char (point-min)) (let (result) (while (re-search-forward (rx bol (group (+ (not space))) From 2a5c946f8793d712c8739629d1bfdb14146c69cf Mon Sep 17 00:00:00 2001 From: Jens Schmidt Date: Sat, 20 May 2023 23:03:29 +0200 Subject: [PATCH 14/54] Preserve mark in comint-history-isearch This preserves mark in `comint-history-isearch-backward' and friends, which tend to set the mark on completion of the isearch to unexpected positions. * lisp/comint.el (comint-history-isearch-end): Set `isearch-opoint' to point. (Bug#63616) --- lisp/comint.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lisp/comint.el b/lisp/comint.el index 682b555a33c..328b073dc8a 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -1542,6 +1542,8 @@ Intended to be added to `isearch-mode-hook' in `comint-mode'." (setq isearch-message-function nil) (setq isearch-wrap-function nil) (setq isearch-push-state-function nil) + ;; Force isearch to not change mark. + (setq isearch-opoint (point)) (kill-local-variable 'isearch-lazy-count) (remove-hook 'isearch-mode-end-hook 'comint-history-isearch-end t) (unless isearch-suspended From dd3e4e14fdc516c7c0f3668601b0b0703b304251 Mon Sep 17 00:00:00 2001 From: Jens Schmidt Date: Sat, 20 May 2023 23:46:42 +0200 Subject: [PATCH 15/54] Remove obsolete information from Gnus manual The Gnus manual was still referencing long-removed external marks in section "Archiving Mails". Without external marks, that section is almost pointless, so remove it completely. * doc/misc/gnus.texi (Archiving Mail): Remove section. (Top, Browsing the Web): Remove references to "Archiving Mail". (Bug#63497) --- doc/misc/gnus.texi | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/doc/misc/gnus.texi b/doc/misc/gnus.texi index f0d3c75d055..d77d4be1bee 100644 --- a/doc/misc/gnus.texi +++ b/doc/misc/gnus.texi @@ -713,7 +713,6 @@ Choosing a Mail Back End Browsing the Web -* Archiving Mail:: * Web Searches:: Creating groups from articles that match a string. * RSS:: Reading RDF site summary. @@ -17244,7 +17243,6 @@ Gnus has been getting a bit of a collection of back ends for providing interfaces to these sources. @menu -* Archiving Mail:: * Web Searches:: Creating groups from articles that match a string. * RSS:: Reading RDF site summary. @end menu @@ -17261,29 +17259,6 @@ cases, it makes a lot of sense to let the Gnus Agent (@pxref{Gnus Unplugged}) handle downloading articles, and then you can read them at leisure from your local disk. No more World Wide Wait for you. -@node Archiving Mail -@subsection Archiving Mail -@cindex archiving mail -@cindex backup of mail - -Some of the back ends, notably @code{nnml}, @code{nnfolder}, and -@code{nnmaildir}, now actually store the article marks with each group. -For these servers, archiving and restoring a group while preserving -marks is fairly simple. - -(Preserving the group level and group parameters as well still -requires ritual dancing and sacrifices to the @file{.newsrc.eld} deity -though.) - -To archive an entire @code{nnml}, @code{nnfolder}, or @code{nnmaildir} -server, take a recursive copy of the server directory. There is no need -to shut down Gnus, so archiving may be invoked by @code{cron} or -similar. You restore the data by restoring the directory tree, and -adding a server definition pointing to that directory in Gnus. The -@ref{Article Backlog}, @ref{Asynchronous Fetching} and other things -might interfere with overwriting data, so you may want to shut down Gnus -before you restore the data. - @node Web Searches @subsection Web Searches @cindex nnweb From d6fb868cdd33af642ff50c62d526d6b4cb44b6b6 Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Mon, 22 May 2023 12:20:27 +0200 Subject: [PATCH 16/54] Fix multihop file name expansion in Tramp * lisp/net/tramp.el (tramp-dissect-file-name): Set hop to nil if NODEFAULT. (Bug#63578) --- lisp/net/tramp.el | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index df2f0850b83..dac2bc8c43c 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1681,8 +1681,9 @@ The structure consists of method, user, domain, host, port, localname (file name on remote host), and hop. Unless NODEFAULT is non-nil, method, user and host are expanded -to their default values. For the other file name parts, no -default values are used." +to their default values. Hop is set to nil if NODEFAULT is non-nil. + +For the other file name parts, no default values are used." (save-match-data (unless (tramp-tramp-file-p name) (tramp-user-error nil "Not a Tramp file name: \"%s\"" name)) @@ -1708,7 +1709,8 @@ default values are used." (when (string-match tramp-postfix-ipv6-regexp host) (setq host (replace-match "" nil t host)))) - (unless nodefault + (if nodefault + (setq hop nil) (when hop (setq v (tramp-dissect-hop-name hop) hop (and hop (tramp-make-tramp-hop-name v)))) From 504ef25ef3616d9ea2845d4d040a533ee70309cf Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Mon, 22 May 2023 12:20:44 +0200 Subject: [PATCH 17/54] ; * etc/NEWS: Fix typos. --- etc/NEWS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index ad6dffae844..a29e0a08cfc 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -140,9 +140,9 @@ various issues with keyboard input of sequences such as 'C-;' and 'C-S-u'. Note that, unlike the X build of Emacs, the PGTK build cannot -automatically switch to text-mode interface (thus emulating -nw) if it -cannot determine the default display; it will instead complain and ask -you to invoke it with the explicit -nw option. +automatically switch to text-mode interface (thus emulating '-nw') if +it cannot determine the default display; it will instead complain and +ask you to invoke it with the explicit '-nw' option. --- ** Emacs no longer reduces the size of the Japanese dictionary. From ecccdc07a098351ed3760d7a2099a34175735886 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Mon, 22 May 2023 13:08:33 +0200 Subject: [PATCH 18/54] shr: allow moving between adjacent anchors * lisp/net/shr.el (shr-urlify): Put shr-tab-stop only over first position. --- lisp/net/shr.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 4e44dfbef03..86987807153 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el @@ -1215,7 +1215,6 @@ START, and END. Note that START and END should be markers." (add-text-properties start (point) (list 'shr-url url - 'shr-tab-stop t 'button t 'category 'shr ; For button.el button buffers. 'help-echo (let ((parsed (url-generic-parse-url @@ -1240,6 +1239,8 @@ START, and END. Note that START and END should be markers." ;; Make separate regions not `eq' so that they'll get ;; separate mouse highlights. 'mouse-face (list 'highlight))) + (when (< start (point)) + (add-text-properties start (1+ start) '(shr-tab-stop t))) ;; Don't overwrite any keymaps that are already in the buffer (i.e., ;; image keymaps). (while (and start From 6ad041939be794a8e325c23e41262303d288ae93 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 22 May 2023 14:20:38 +0300 Subject: [PATCH 19/54] Support 'isearch-allow-scroll' in 'pixel-scroll-precision-mode' * lisp/pixel-scroll.el (pixel-scroll-precision) (pixel-scroll-down, pixel-scroll-up): Put the 'scroll-command' property on these commands. (Bug#63640) --- lisp/pixel-scroll.el | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el index 487144144f5..5f412bf418a 100644 --- a/lisp/pixel-scroll.el +++ b/lisp/pixel-scroll.el @@ -290,6 +290,10 @@ This is and alternative of `scroll-down'. Scope moves upward." (scroll-down 1) ; relay on robust method (pixel-scroll-pixel-down amt)))))) +;; isearch-scroll support +(put 'pixel-scroll-up 'scroll-command t) +(put 'pixel-scroll-down 'scroll-command t) + (defun pixel-bob-at-top-p (amt) "Return non-nil if window-start is at beginning of the current buffer. Window must be vertically scrolled by not more than AMT pixels." @@ -728,6 +732,9 @@ wheel." (message (error-message-string '(end-of-buffer)))))))))) (mwheel-scroll event nil)))) +;; isearch-scroll support +(put 'pixel-scroll-precision 'scroll-command t) + (defun pixel-scroll-kinetic-state (&optional window) "Return the kinetic scroll state of WINDOW. If WINDOW is nil, return the state of the current window. From 5c95239aca211147ffd93735a11d4908fc8a6d4d Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" Date: Mon, 22 May 2023 15:23:39 +0100 Subject: [PATCH 20/54] ; Fix markup of some treesit vars in Elisp manual. * doc/lispref/modes.texi (Parser-based Font Lock): (Parser-based Indentation): * doc/lispref/parsing.texi (Multiple Languages): Use @code in place of @var when the argument is not a metavariable. --- doc/lispref/modes.texi | 10 +++++----- doc/lispref/parsing.texi | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 00298d88f43..cb491d52c50 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -4073,8 +4073,8 @@ replacing syntactic font lock, then the regexp-based font lock. Although parser-based font lock doesn't share the same customization variables with regexp-based font lock, it uses similar customization -schemes. The tree-sitter counterpart of @var{font-lock-keywords} is -@var{treesit-font-lock-settings}. +schemes. The tree-sitter counterpart of @code{font-lock-keywords} is +@code{treesit-font-lock-settings}. @cindex tree-sitter fontifications, overview @cindex fontifications with tree-sitter, overview @@ -4108,9 +4108,9 @@ To setup tree-sitter fontification, a major mode should first set @code{treesit-major-mode-setup}. @defun treesit-font-lock-rules &rest query-specs -This function is used to set @var{treesit-font-lock-settings}. It +This function is used to set @code{treesit-font-lock-settings}. It takes care of compiling queries and other post-processing, and outputs -a value that @var{treesit-font-lock-settings} accepts. Here's an +a value that @code{treesit-font-lock-settings} accepts. Here's an example: @example @@ -4981,7 +4981,7 @@ below: then the major mode needs only to write some indentation rules and the engine takes care of the rest. To enable the parser-based indentation engine, either set -@var{treesit-simple-indent-rules} and call +@code{treesit-simple-indent-rules} and call @code{treesit-major-mode-setup}, or equivalently, set the value of @code{indent-line-function} to @code{treesit-indent}. diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi index cba323d3a56..b70f953f8ed 100644 --- a/doc/lispref/parsing.texi +++ b/doc/lispref/parsing.texi @@ -1644,9 +1644,9 @@ directly translate into operations shown above. @end example @defun treesit-range-rules &rest query-specs -This function is used to set @var{treesit-range-settings}. It -takes care of compiling queries and other post-processing, and outputs -a value that @var{treesit-range-settings} can have. +This function is used to set @code{treesit-range-settings}. It takes +care of compiling queries and other post-processing, and outputs a +value that @code{treesit-range-settings} can have. It takes a series of @var{query-spec}s, where each @var{query-spec} is a @var{query} preceded by zero or more @var{keyword}/@var{value} From 64dbbde3b77c3d81445cd0faa2237fe0997ed741 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 22 May 2023 21:23:58 +0300 Subject: [PATCH 21/54] Fix visiting HTML files encoded in iso-2022 variants * lisp/international/mule.el (sgml-xml-auto-coding-function) (sgml-html-meta-auto-coding-function): Handle coding-systems whose coding-system-type is iso-2022. (Bug#63644) --- lisp/international/mule.el | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/lisp/international/mule.el b/lisp/international/mule.el index 25b90b49c8f..2b44a2e0645 100644 --- a/lisp/international/mule.el +++ b/lisp/international/mule.el @@ -2484,10 +2484,12 @@ This function is intended to be added to `auto-coding-functions'." ;; called as part of visiting a file, as opposed ;; to when saving a buffer to a file. (if (and enable-multibyte-characters - ;; 'charset' will signal an error in - ;; coding-system-equal, since it isn't a - ;; coding-system. So test that up front. + ;; 'charset' and 'iso-2022' will signal + ;; an error in coding-system-equal, since + ;; they aren't coding-systems. So test + ;; that up front. (not (equal sym-type 'charset)) + (not (equal sym-type 'iso-2022)) (coding-system-equal 'utf-8 sym-type) (coding-system-equal 'utf-8 bfcs-type)) buffer-file-coding-system @@ -2540,11 +2542,13 @@ This function is intended to be added to `auto-coding-functions'." (bfcs-type (coding-system-type buffer-file-coding-system))) (if (and enable-multibyte-characters - ;; 'charset' will signal an error in - ;; coding-system-equal, since it isn't a - ;; coding-system. So test that up front. + ;; 'charset' and 'iso-2022' will signal an error + ;; in coding-system-equal, since they aren't + ;; coding-systems. So test that up front. (not (equal sym-type 'charset)) (not (equal bfcs-type 'charset)) + (not (equal sym-type 'iso-2022)) + (not (equal bfcs-type 'iso-2022)) (coding-system-equal 'utf-8 sym-type) (coding-system-equal 'utf-8 bfcs-type)) buffer-file-coding-system From fe22bf503fb724816a6c629e2e6d21c1edf8b5f7 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Mon, 22 May 2023 21:31:56 +0300 Subject: [PATCH 22/54] ; * lisp/progmodes/project.el (project-switch-use-entire-map): Doc fix. --- lisp/progmodes/project.el | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index a18b918db62..35b57ee4819 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1759,11 +1759,12 @@ invoked immediately without any dispatch menu." (symbol :tag "Single command"))) (defcustom project-switch-use-entire-map nil - "Make `project-switch-project' use entire `project-prefix-map'. + "Whether `project-switch-project' will use the entire `project-prefix-map'. If nil, `project-switch-project' will only recognize commands -listed in `project-switch-commands' and signal an error when -others are invoked. Otherwise, all keys in `project-prefix-map' -are legal even if they aren't listed in the dispatch menu." +listed in `project-switch-commands', and will signal an error +when other commands are invoked. If this is non-nil, all the +keys in `project-prefix-map' are valid even if they aren't +listed in the dispatch menu produced from `project-switch-commands'." :type 'boolean :group 'project :version "28.1") From a347b26cba2124496b1fa5adb75f43c8a05842a6 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 23 May 2023 14:30:31 +0300 Subject: [PATCH 23/54] Disable loading SQLite3 extensions when SQLite3 version is too old * src/sqlite.c (HAVE_LOAD_EXTENSION): Define to 1 only if enabling/disabling extension loading is supported as well. (load_dll_functions, Fsqlite_load_extension): Condition on HAVE_LOAD_EXTENSION, not on HAVE_SQLITE3_LOAD_EXTENSION. (Bug#63653) --- src/sqlite.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/sqlite.c b/src/sqlite.c index 77ce61ba657..852e3746ef4 100644 --- a/src/sqlite.c +++ b/src/sqlite.c @@ -32,6 +32,17 @@ YOSHIDA , which can be found at: #include +/* Support for loading SQLite extensions requires the ability to + enable and disable loading of extensions (by default this is + disabled, and we want to keep it that way). The required macro is + available since SQLite 3.13. */ +# if defined HAVE_SQLITE3_LOAD_EXTENSION && \ + defined SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION +# define HAVE_LOAD_EXTENSION 1 +# else +# define HAVE_LOAD_EXTENSION 0 +# endif + #ifdef WINDOWSNT # include @@ -77,7 +88,7 @@ DEF_DLL_FN (SQLITE_API int, sqlite3_exec, DEF_DLL_FN (SQLITE_API int, sqlite3_prepare_v2, (sqlite3*, const char*, int, sqlite3_stmt**, const char**)); -# ifdef HAVE_SQLITE3_LOAD_EXTENSION +# if HAVE_LOAD_EXTENSION DEF_DLL_FN (SQLITE_API int, sqlite3_load_extension, (sqlite3*, const char*, const char*, char**)); # undef sqlite3_load_extension @@ -175,7 +186,7 @@ load_dll_functions (HMODULE library) LOAD_DLL_FN (library, sqlite3_column_text); LOAD_DLL_FN (library, sqlite3_column_name); LOAD_DLL_FN (library, sqlite3_exec); -# ifdef HAVE_SQLITE3_LOAD_EXTENSION +# if HAVE_LOAD_EXTENSION LOAD_DLL_FN (library, sqlite3_load_extension); LOAD_DLL_FN (library, sqlite3_db_config); # endif @@ -675,7 +686,7 @@ DEFUN ("sqlite-pragma", Fsqlite_pragma, Ssqlite_pragma, 2, 2, 0, SSDATA (concat2 (build_string ("PRAGMA "), pragma))); } -#ifdef HAVE_SQLITE3_LOAD_EXTENSION +#if HAVE_LOAD_EXTENSION DEFUN ("sqlite-load-extension", Fsqlite_load_extension, Ssqlite_load_extension, 2, 2, 0, doc: /* Load an SQlite MODULE into DB. @@ -750,7 +761,7 @@ Only modules on Emacs' list of allowed modules can be loaded. */) } return Qnil; } -#endif /* HAVE_SQLITE3_LOAD_EXTENSION */ +#endif /* HAVE_LOAD_EXTENSION */ DEFUN ("sqlite-next", Fsqlite_next, Ssqlite_next, 1, 1, 0, doc: /* Return the next result set from SET. @@ -860,7 +871,7 @@ syms_of_sqlite (void) defsubr (&Ssqlite_commit); defsubr (&Ssqlite_rollback); defsubr (&Ssqlite_pragma); -#ifdef HAVE_SQLITE3_LOAD_EXTENSION +#if HAVE_LOAD_EXTENSION defsubr (&Ssqlite_load_extension); #endif defsubr (&Ssqlite_next); From 117b29c6f6681e4ae0710a9f90f1b8d274afc7c0 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 23 May 2023 14:58:39 +0300 Subject: [PATCH 24/54] ; Improve documentation of Isearch command properties * doc/emacs/display.texi (Scrolling): * doc/emacs/search.texi (Not Exiting Isearch): Improve documentation and indexing of 'scroll-command', 'isearch-scroll', and 'isearch-move' properties. --- doc/emacs/display.texi | 5 ++++- doc/emacs/search.texi | 35 ++++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi index 6b2eb014c82..fa8ca4cbf17 100644 --- a/doc/emacs/display.texi +++ b/doc/emacs/display.texi @@ -127,7 +127,10 @@ command leaves point in the window. This variable affects all the scroll commands documented in this section, as well as scrolling with the mouse wheel (@pxref{Mouse Commands}); in general, it affects any command that has a non-@code{nil} @code{scroll-command} property. -@xref{Property Lists,,, elisp, The Emacs Lisp Reference Manual}. +@xref{Property Lists,,, elisp, The Emacs Lisp Reference Manual}. The +same property also causes Emacs not to exit incremental search when +one of these commands is invoked and @code{isearch-allow-scroll} is +non-@code{nil} (@pxref{Not Exiting Isearch}). @vindex fast-but-imprecise-scrolling Sometimes, particularly when you hold down keys such as @kbd{C-v} diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi index fb79fe8f3fc..45378d95f65 100644 --- a/doc/emacs/search.texi +++ b/doc/emacs/search.texi @@ -587,26 +587,30 @@ i.e., they don't terminate the search, even if @item Scrolling Commands @cindex scrolling commands, during incremental search @vindex isearch-allow-scroll - Normally, scrolling commands exit incremental search. If you change -the variable @code{isearch-allow-scroll} to a non-@code{nil} value, -that enables the use of the scroll-bar, as well as keyboard scrolling -commands like @kbd{C-v}, @kbd{M-v}, and @kbd{C-l} (@pxref{Scrolling}). -This applies only to calling these commands via their bound key -sequences---typing @kbd{M-x} will still exit the search. You can give -prefix arguments to these commands in the usual way. This feature -normally won't let you scroll the current match out of visibility; but -if you customize @code{isearch-allow-scroll} to the special value -@code{unlimited}, that restriction is lifted. +@cindex @code{scroll-command} property, and incremental search + Normally, scrolling commands exit incremental search. But if you +change the variable @code{isearch-allow-scroll} to a non-@code{nil} +value, that enables the use of the scroll-bar, as well as keyboard +scrolling commands like @kbd{C-v}, @kbd{M-v}, and @kbd{C-l} +(@pxref{Scrolling}), which have a non-@code{nil} @code{scroll-command} +property, without exiting the search. This applies only to calling +these commands via their bound key sequences---typing @kbd{M-x} will +still exit the search. You can give prefix arguments to these +commands in the usual way. This feature normally won't let you scroll +the current match out of visibility; but if you customize +@code{isearch-allow-scroll} to the special value @code{unlimited}, +that restriction is lifted. +@cindex @code{isearch-scroll} property +@cindex prevent commands from exiting incremental search The @code{isearch-allow-scroll} feature also affects some other commands, such as @kbd{C-x 2} (@code{split-window-below}) and @kbd{C-x ^} (@code{enlarge-window}), which don't exactly scroll but do -affect where the text appears on the screen. It applies to any -command whose name has a non-@code{nil} @code{isearch-scroll} -property. So you can control which commands are affected by changing -these properties. +affect where the text appears on the screen. In fact, it affects +any command that has a non-@code{nil} @code{isearch-scroll} property. +So you can control which commands are affected by changing these +properties. -@cindex prevent commands from exiting incremental search For example, to make @kbd{C-h l} usable within an incremental search in all future Emacs sessions, use @kbd{C-h c} to find what command it runs (@pxref{Key Help}), which is @code{view-lossage}. Then you can @@ -643,6 +647,7 @@ you can extend the search string by holding down the shift key while typing cursor motion commands. It will yank text that ends at the new position after moving point in the current buffer. +@cindex @code{isearch-move} property When @code{isearch-yank-on-move} is @code{t}, you can extend the search string without using the shift key for cursor motion commands, but it applies only for certain motion command that have the From 6f6071c52616cc30bc28083688a3ad8d70ce713e Mon Sep 17 00:00:00 2001 From: Robert Pluim Date: Mon, 22 May 2023 15:44:21 +0200 Subject: [PATCH 25/54] Avoid duplicate load-path entry when generating package autoloads 'file-name-directory' produces a path ending in '/', so that needs to be run through 'directory-file-name' to avoid duplicate entries in 'load-path'. (Bug#63625) * lisp/emacs-lisp/package.el (package-generate-autoloads): Call 'directory-file-name' on the directory of 'load-file-name'. --- lisp/emacs-lisp/package.el | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 293c1c39ca1..0d90e4a4059 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -1110,8 +1110,12 @@ untar into a directory named DIR; otherwise, signal an error." ;; Add the directory that will contain the autoload file to ;; the load path. We don't hard-code `pkg-dir', to avoid ;; issues if the package directory is moved around. - (or (and load-file-name (file-name-directory load-file-name)) - (car load-path))))) + ;; `loaddefs-generate' has code to do this for us, but it's + ;; not currently exposed. (Bug#63625) + (or (and load-file-name + (directory-file-name + (file-name-directory load-file-name))) + (car load-path))))) (let ((buf (find-buffer-visiting output-file))) (when buf (kill-buffer buf))) auto-name)) From 0abb79ca09a9d0118e2bae7a4d00cd8f8a537795 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Mon, 22 May 2023 18:49:26 +0200 Subject: [PATCH 26/54] Avoid duplicates when adding package dirs to load-path Do not merge to master, we're going to delete this code there. * lisp/emacs-lisp/package.el (package-activate-1): Check if the path we're about to add is already in 'load-path', since package autoload files have been updating 'load-path' for a decade. --- lisp/emacs-lisp/package.el | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 0d90e4a4059..340ca9400fa 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -904,7 +904,12 @@ correspond to previously loaded files." (package--reload-previously-loaded pkg-desc)) (with-demoted-errors "Error loading autoloads: %s" (load (package--autoloads-file-name pkg-desc) nil t)) - (add-to-list 'load-path (directory-file-name pkg-dir))) + ;; FIXME: Since 2013 (commit 4fac34cee97a), the autoload files take + ;; care of changing the `load-path', so maybe it's time to + ;; remove this fallback code? + (unless (or (member (file-name-as-directory pkg-dir) load-path) + (member (directory-file-name pkg-dir) load-path)) + (add-to-list 'load-path pkg-dir))) ;; Add info node. (when (file-exists-p (expand-file-name "dir" pkg-dir)) ;; FIXME: not the friendliest, but simple. From 5aadb87d6f6e3d9d755d4b6f6d124040c1bcfeee Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 23 May 2023 17:44:23 +0300 Subject: [PATCH 27/54] Fix 'use-dialog-box-p' and friends * lisp/subr.el (use-dialog-box-p): Use dialog boxes also when invoked from some window-system gesture. (Bug#63655) (y-or-n-p): Fix the description in the doc string of conditions under which a dialog box will be used. * src/fns.c (Fyes_or_no_p): Use the same condition for dialog boxes as in 'use-dialog-box-p'. Fix the description in the doc string of conditions under which a dialog box will be used. * doc/lispref/minibuf.texi (Multiple Queries, Yes-or-No Queries): Fix the description of conditions under which a dialog box will be used. --- doc/lispref/minibuf.texi | 30 ++++++++++++++++-------------- lisp/subr.el | 7 +++++-- src/fns.c | 16 +++++++++++----- 3 files changed, 32 insertions(+), 21 deletions(-) diff --git a/doc/lispref/minibuf.texi b/doc/lispref/minibuf.texi index a4916ecda30..9a386ff310d 100644 --- a/doc/lispref/minibuf.texi +++ b/doc/lispref/minibuf.texi @@ -2174,13 +2174,14 @@ will not have serious consequences. @code{yes-or-no-p} is suitable for more momentous questions, since it requires three or four characters to answer. - If either of these functions is called in a command that was invoked -using the mouse---more precisely, if @code{last-nonmenu-event} -(@pxref{Command Loop Info}) is either @code{nil} or a list---then it -uses a dialog box or pop-up menu to ask the question. Otherwise, it -uses keyboard input. You can force use either of the mouse or of keyboard -input by binding @code{last-nonmenu-event} to a suitable value around -the call. + If either of these functions is called in a command that was +invoked using the mouse or some other window-system gesture, or in a +command invoked via a menu, then they use a dialog box or pop-up menu +to ask the question if dialog boxes are supported. Otherwise, they +use keyboard input. You can force use either of the mouse or of +keyboard input by binding @code{last-nonmenu-event} to a suitable +value around the call---bind it to @code{t} to force keyboard +interaction, and to a list to force dialog boxes. Both @code{yes-or-no-p} and @code{y-or-n-p} use the minibuffer. @@ -2378,13 +2379,14 @@ Normally, @code{map-y-or-n-p} binds @code{cursor-in-echo-area} while prompting. But if @var{no-cursor-in-echo-area} is non-@code{nil}, it does not do that. -If @code{map-y-or-n-p} is called in a command that was invoked using the -mouse---more precisely, if @code{last-nonmenu-event} (@pxref{Command -Loop Info}) is either @code{nil} or a list---then it uses a dialog box -or pop-up menu to ask the question. In this case, it does not use -keyboard input or the echo area. You can force use either of the mouse or -of keyboard input by binding @code{last-nonmenu-event} to a suitable -value around the call. +If @code{map-y-or-n-p} is called in a command that was invoked using +the mouse or some other window-system gesture, or a command invoked +via a menu, then it uses a dialog box or pop-up menu to ask the +question if dialog boxes are supported. In this case, it does not use +keyboard input or the echo area. You can force use either of the +mouse or of keyboard input by binding @code{last-nonmenu-event} to a +suitable value around the call---bind it to @code{t} to force keyboard +interaction, and to a list to force dialog boxes. The return value of @code{map-y-or-n-p} is the number of objects acted on. @end defun diff --git a/lisp/subr.el b/lisp/subr.el index 52227b5261c..950902039b1 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -3544,6 +3544,8 @@ confusing to some users.") "Return non-nil if the current command should prompt the user via a dialog box." (and last-input-event ; not during startup (or (consp last-nonmenu-event) ; invoked by a mouse event + (and (null last-nonmenu-event) + (consp last-input-event)) from--tty-menu-p) ; invoked via TTY menu use-dialog-box)) @@ -3574,8 +3576,9 @@ If the user enters `recenter', `scroll-up', or `scroll-down' responses, perform the requested window recentering or scrolling and ask again. -Under a windowing system a dialog box will be used if `last-nonmenu-event' -is nil and `use-dialog-box' is non-nil. +If dialog boxes are supported, this function will use a dialog box +if `use-dialog-box' is non-nil and the last input event was produced +by a mouse, or by some window-system gesture, or via a menu. By default, this function uses the minibuffer to read the key. If `y-or-n-p-use-read-key' is non-nil, `read-key' is used diff --git a/src/fns.c b/src/fns.c index e8cd6211d6d..2ed62d6e8c6 100644 --- a/src/fns.c +++ b/src/fns.c @@ -3185,16 +3185,21 @@ has been confirmed. If the `use-short-answers' variable is non-nil, instead of asking for \"yes\" or \"no\", this function will ask for \"y\" or \"n\". -If dialog boxes are supported, a dialog box will be used -if `last-nonmenu-event' is nil, and `use-dialog-box' is non-nil. */) +If dialog boxes are supported, this function will use a dialog box +if `use-dialog-box' is non-nil and the last input event was produced +by a mouse, or by some window-system gesture, or via a menu. */) (Lisp_Object prompt) { - Lisp_Object ans; + Lisp_Object ans, val; CHECK_STRING (prompt); - if ((NILP (last_nonmenu_event) || CONSP (last_nonmenu_event)) - && use_dialog_box && ! NILP (last_input_event)) + if (!NILP (last_input_event) + && (CONSP (last_nonmenu_event) + || (NILP (last_nonmenu_event) && CONSP (last_input_event)) + || (val = find_symbol_value (Qfrom__tty_menu_p), + (!NILP (val) && !EQ (val, Qunbound)))) + && use_dialog_box) { Lisp_Object pane, menu, obj; redisplay_preserve_echo_area (4); @@ -6358,4 +6363,5 @@ The same variable also affects the function `read-answer'. */); defsubr (&Sbuffer_line_statistics); DEFSYM (Qreal_this_command, "real-this-command"); + DEFSYM (Qfrom__tty_menu_p, "from--tty-menu-p"); } From 765edc204d45c0eb6d31e92c661355c1bd7315a9 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 23 May 2023 17:53:07 +0300 Subject: [PATCH 28/54] ; Support SQLite3 extensions on macOS * src/sqlite.c (Fsqlite_load_extension): Support *.dylib extensions. (Bug#63653) --- src/sqlite.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/sqlite.c b/src/sqlite.c index 852e3746ef4..fd528f2b0d5 100644 --- a/src/sqlite.c +++ b/src/sqlite.c @@ -730,10 +730,12 @@ Only modules on Emacs' list of allowed modules can be loaded. */) bool do_allow = false; for (const char **allow = allowlist; *allow; allow++) { - if (strlen (*allow) < strlen (name) - && !strncmp (*allow, name, strlen (*allow)) - && (!strcmp (name + strlen (*allow), ".so") - || !strcasecmp (name + strlen (*allow), ".dll"))) + ptrdiff_t allow_len = strlen (*allow); + if (allow_len < strlen (name) + && !strncmp (*allow, name, allow_len) + && (!strcmp (name + allow_len, ".so") + ||!strcmp (name + allow_len, ".dylib") + || !strcasecmp (name + allow_len, ".dll"))) { do_allow = true; break; From 1b9812af80b6ceec8418636dbf84c0fbcd3ab694 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 23 May 2023 18:04:24 +0300 Subject: [PATCH 29/54] ; * etc/PROBLEMS: Document problem with GnuPG 2.4.1. (Bug#63256) --- etc/PROBLEMS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/etc/PROBLEMS b/etc/PROBLEMS index c0cb5b0d8bb..82ab48fa514 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -516,6 +516,13 @@ directory copy is ineffective. This is due to an arbitrary limit in certain versions of awk. The solution is to use gawk (GNU awk). +*** Saving, via EasyPG, a file encrypted with GnuPG hangs + +This is known to happen with GnuPG v2.4.1. The only known workaround +is to downgrade to a version of GnuPG older than 2.4.1 (or, in the +future, upgrade to a newer version which solves the problem, when such +a fixed version becomes available) + ** Problems with hostname resolution *** Emacs does not know your host's fully-qualified domain name. From 212884f2bfed7f00e58aad183edd20ecc2a23e71 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Tue, 23 May 2023 18:05:07 +0300 Subject: [PATCH 30/54] ; Fix last change. --- etc/PROBLEMS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/PROBLEMS b/etc/PROBLEMS index 82ab48fa514..5b9b5ee4ead 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -521,7 +521,7 @@ The solution is to use gawk (GNU awk). This is known to happen with GnuPG v2.4.1. The only known workaround is to downgrade to a version of GnuPG older than 2.4.1 (or, in the future, upgrade to a newer version which solves the problem, when such -a fixed version becomes available) +a fixed version becomes available). ** Problems with hostname resolution From 5c6517a115d5523ddde43725b415da52ba6ee64c Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 25 May 2023 08:57:28 +0300 Subject: [PATCH 31/54] ; * lisp/menu-bar.el (popup-menu): Doc fix. --- lisp/menu-bar.el | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index d020cf6e90a..88873ce5e24 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -1,4 +1,4 @@ -;;; menu-bar.el --- define a default menu bar -*- lexical-binding: t; -*- +2070;;; menu-bar.el --- define a default menu bar -*- lexical-binding: t; -*- ;; Copyright (C) 1993-1995, 2000-2023 Free Software Foundation, Inc. @@ -2567,10 +2567,11 @@ See `menu-bar-mode' for more information." binding))) (defun popup-menu (menu &optional position prefix from-menu-bar) - "Popup the given menu and call the selected option. + "Popup MENU and call the selected option. MENU can be a keymap, an easymenu-style menu or a list of keymaps as for `x-popup-menu'. -The menu is shown at the place where POSITION specifies. +The menu is shown at the location specified by POSITION, which +defaults to the place of the mouse click that popped the menu. For the form of POSITION, see `popup-menu-normalize-position'. PREFIX is the prefix argument (if any) to pass to the command. FROM-MENU-BAR, if non-nil, means we are dropping one of menu-bar's menus." From a72a1f24fcb56d1a4e622f189d5a56e84f346097 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 25 May 2023 08:58:42 +0300 Subject: [PATCH 32/54] ; Fix last change. --- lisp/menu-bar.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index 88873ce5e24..f6b87d1078d 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -1,4 +1,4 @@ -2070;;; menu-bar.el --- define a default menu bar -*- lexical-binding: t; -*- +;;; menu-bar.el --- define a default menu bar -*- lexical-binding: t; -*- ;; Copyright (C) 1993-1995, 2000-2023 Free Software Foundation, Inc. From 709d9020021eaaf1e1475f61b72b2405f4fd0bb3 Mon Sep 17 00:00:00 2001 From: Michael Albinus Date: Thu, 25 May 2023 15:40:45 +0200 Subject: [PATCH 33/54] Make last Tramp change less invasive * lisp/net/tramp.el (tramp-dissect-file-name): Revert last change. (tramp-handle-file-name-as-directory) (tramp-handle-file-name-directory): Let-bind `tramp-default-proxies-alist'. --- lisp/net/tramp.el | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index dac2bc8c43c..9f868ccdaa0 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1681,9 +1681,8 @@ The structure consists of method, user, domain, host, port, localname (file name on remote host), and hop. Unless NODEFAULT is non-nil, method, user and host are expanded -to their default values. Hop is set to nil if NODEFAULT is non-nil. - -For the other file name parts, no default values are used." +to their default values. For the other file name parts, no +default values are used." (save-match-data (unless (tramp-tramp-file-p name) (tramp-user-error nil "Not a Tramp file name: \"%s\"" name)) @@ -1709,8 +1708,7 @@ For the other file name parts, no default values are used." (when (string-match tramp-postfix-ipv6-regexp host) (setq host (replace-match "" nil t host)))) - (if nodefault - (setq hop nil) + (unless nodefault (when hop (setq v (tramp-dissect-hop-name hop) hop (and hop (tramp-make-tramp-hop-name v)))) @@ -3894,8 +3892,10 @@ Let-bind it when necessary.") (defun tramp-handle-file-name-as-directory (file) "Like `file-name-as-directory' for Tramp files." ;; `file-name-as-directory' would be sufficient except localname is - ;; the empty string. - (let ((v (tramp-dissect-file-name file t))) + ;; the empty string. Suppress adding a hop to + ;; `tramp-default-proxies-alist' due to non-expanded default values. + (let ((v (tramp-dissect-file-name file t)) + tramp-default-proxies-alist) ;; Run the command on the localname portion only unless we are in ;; completion mode. (tramp-make-tramp-file-name @@ -3985,8 +3985,10 @@ Let-bind it when necessary.") "Like `file-name-directory' for Tramp files." ;; Everything except the last filename thing is the directory. We ;; cannot apply `with-parsed-tramp-file-name', because this expands - ;; the remote file name parts. - (let ((v (tramp-dissect-file-name file t))) + ;; the remote file name parts. Suppress adding a hop to + ;; `tramp-default-proxies-alist' due to non-expanded default values. + (let ((v (tramp-dissect-file-name file t)) + tramp-default-proxies-alist) ;; Run the command on the localname portion only. If this returns ;; nil, mark also the localname part of `v' as nil. (tramp-make-tramp-file-name From d292d282292b8ce1f4e1ba97d0110178153f73c5 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Thu, 25 May 2023 20:50:46 +0300 Subject: [PATCH 34/54] Fix rare crashes in 'try_window_reusing_current_matrix' * src/xdisp.c (try_window_reusing_current_matrix): Make sure we never use a mode-line glyph row to start displaying scrolled-in rows. (Bug#63711) --- src/xdisp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/xdisp.c b/src/xdisp.c index aeba47e4c16..2ddfdf0d51b 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -21081,8 +21081,10 @@ try_window_reusing_current_matrix (struct window *w) pt_row = first_row_to_display; } + if (first_row_to_display->y >= yb) + return false; + /* Start displaying at the start of first_row_to_display. */ - eassert (first_row_to_display->y < yb); init_to_row_start (&it, w, first_row_to_display); nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix) From b62a2b08b80ecf855096daf1e9e84b3f7bc7622a Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Thu, 25 May 2023 21:24:23 +0300 Subject: [PATCH 35/54] Add vc-create/switch/print-branch to menu and update documentation (bug#63690) * doc/emacs/maintaining.texi (VC Change Log): Add 'C-x v b l' (vc-print-branch-log). (Creating Branches): Add @kindex and @findex for vc-create-branch. (Switching Branches): Add @kindex and @findex for vc-switch-branch. * lisp/vc/vc-hooks.el (vc-menu-map): Add menu items for new commands vc-create-branch and vc-switch-branch, and also vc-print-branch-log. * lisp/vc/vc.el (vc-print-branch-log): Improve docstring. --- doc/emacs/maintaining.texi | 18 +++++++++++++++++- lisp/vc/vc-hooks.el | 9 +++++++++ lisp/vc/vc.el | 3 ++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index 7d49e28d11f..06f44a88aab 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi @@ -999,6 +999,10 @@ Display the change history for the current fileset Display the change history for the current repository (@code{vc-print-root-log}). +@item C-x v b l +Display the change history for another branch +(@code{vc-print-branch-log}). + @item C-x v I Display the changes that a ``pull'' operation will retrieve (@code{vc-log-incoming}). @@ -1063,6 +1067,13 @@ showing only the first line of each log entry. However, you can type @file{*vc-change-log*} buffer to reveal the entire log entry for the revision at point. A second @key{RET} hides it again. +@kindex C-x v b l +@findex vc-print-branch-log + @kbd{C-x v b l @var{branch-name} @key{RET}} (@code{vc-print-branch-log}) +displays a @file{*vc-change-log*} buffer showing the history of the +version-controlled directory tree like @code{vc-print-root-log} does, +but in another branch provided as an argument. + @kindex C-x v I @kindex C-x v O @findex vc-log-incoming @@ -1523,6 +1534,8 @@ switch to another branch using the @kbd{svn switch} command. With Mercurial, command @kbd{hg update} is used to switch to another branch. +@kindex C-x v b s +@findex vc-switch-branch The VC command to switch to another branch in the current directory is @kbd{C-x v b s @var{branch-name} @key{RET}} (@code{vc-switch-branch}). @@ -1673,9 +1686,12 @@ branch ID for a branch starting at the current revision. For example, if the current revision is 2.5, the branch ID should be 2.5.1, 2.5.2, and so on, depending on the number of existing branches at that point. +@kindex C-x v b c +@findex vc-create-branch This procedure will not work for distributed version control systems like git or Mercurial. For those systems you should use the command -@code{vc-create-branch} (@kbd{C-x v b c}) instead. +@code{vc-create-branch} (@kbd{C-x v b c @var{branch-name} @key{RET}}) +instead. To create a new branch at an older revision (one that is no longer the head of a branch), first select that revision (@pxref{Switching diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el index e242d1e48e2..b559a776c09 100644 --- a/lisp/vc/vc-hooks.el +++ b/lisp/vc/vc-hooks.el @@ -897,6 +897,15 @@ In the latter case, VC mode is deactivated for this buffer." (bindings--define-key map [vc-create-tag] '(menu-item "Create Tag" vc-create-tag :help "Create version tag")) + (bindings--define-key map [vc-print-branch-log] + '(menu-item "Show Branch History..." vc-print-branch-log + :help "List the change log for a branch")) + (bindings--define-key map [vc-switch-branch] + '(menu-item "Switch Branch..." vc-switch-branch + :help "Switch to another branch")) + (bindings--define-key map [vc-create-branch] + '(menu-item "Create Branch..." vc-create-branch + :help "Make a new branch")) (bindings--define-key map [separator1] menu-bar-separator) (bindings--define-key map [vc-annotate] '(menu-item "Annotate" vc-annotate diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index c64da1233d1..ba981545085 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -2851,7 +2851,8 @@ with its diffs (if the underlying VCS backend supports that)." ;;;###autoload (defun vc-print-branch-log (branch) - "Show the change log for BRANCH root in a window." + "Show the change log for BRANCH in a window. +The command prompts for the branch to log." (interactive (let* ((backend (vc-responsible-backend default-directory)) (rootdir (vc-call-backend backend 'root default-directory))) From 3afe4a42e90f4eb937b81879548ffbfa7e1f6599 Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Thu, 25 May 2023 21:33:11 +0300 Subject: [PATCH 36/54] * lisp/vc/vc-annotate.el (vc-annotate-mode-menu): Quote vc-annotate-backend. When unquoted it might get the nil value when vc-annotate.el is loaded in non-vc-controlled buffer (bug#63689). --- lisp/vc/vc-annotate.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/vc/vc-annotate.el b/lisp/vc/vc-annotate.el index 70057a6aac7..d83660f9d79 100644 --- a/lisp/vc/vc-annotate.el +++ b/lisp/vc/vc-annotate.el @@ -330,7 +330,7 @@ cover the range from the oldest annotation to the newest." ["Show changeset diff of revision at line" vc-annotate-show-changeset-diff-revision-at-line :enable - (eq 'repository (vc-call-backend ,vc-annotate-backend 'revision-granularity)) + (eq 'repository (vc-call-backend vc-annotate-backend 'revision-granularity)) :help "Visit the diff of the revision at line from its previous revision"] ["Visit revision at line" vc-annotate-find-revision-at-line :help "Visit the revision identified in the current line"])) From e5f42706ce2fd00d1ac9249a8760a88781f09a2f Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Thu, 25 May 2023 21:40:38 +0300 Subject: [PATCH 37/54] * lisp/progmodes/project.el: Move :safe from defcustom to autoload (bug#63469) (project-vc-ignores, project-vc-merge-submodules) (project-vc-include-untracked, project-vc-name) (project-vc-extra-root-markers, project-kill-buffers-display-buffer-list): Autoload the line that puts 'safe-local-variable' property on defcustom symbol instead of using the :safe keyword. --- lisp/progmodes/project.el | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 35b57ee4819..e2112276379 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -401,8 +401,8 @@ the buffer's value of `default-directory'." (defcustom project-vc-ignores nil "List of patterns to add to `project-ignores'." - :type '(repeat string) - :safe #'listp) + :type '(repeat string)) +;;;###autoload(put 'project-vc-ignores 'safe-local-variable #'listp) (defcustom project-vc-merge-submodules t "Non-nil to consider submodules part of the parent project. @@ -411,14 +411,14 @@ After changing this variable (using Customize or .dir-locals.el) you might have to restart Emacs to see the effect." :type 'boolean :version "28.1" - :package-version '(project . "0.2.0") - :safe #'booleanp) + :package-version '(project . "0.2.0")) +;;;###autoload(put 'project-vc-merge-submodules 'safe-local-variable #'booleanp) (defcustom project-vc-include-untracked t "When non-nil, the VC-aware project backend includes untracked files." :type 'boolean - :version "29.1" - :safe #'booleanp) + :version "29.1") +;;;###autoload(put 'project-vc-include-untracked 'safe-local-variable #'booleanp) (defcustom project-vc-name nil "When non-nil, the name of the current VC-aware project. @@ -428,8 +428,8 @@ its name, is by setting this in .dir-locals.el." :type '(choice (const :tag "Default to the base name" nil) (string :tag "Custom name")) :version "29.1" - :package-version '(project . "0.9.0") - :safe #'stringp) + :package-version '(project . "0.9.0")) +;;;###autoload(put 'project-vc-name 'safe-local-variable #'stringp) ;; Not using regexps because these wouldn't work in Git pathspecs, in ;; case we decide we need to be able to list nested projects. @@ -456,8 +456,8 @@ In either case, their behavior will still obey the relevant variables, such as `project-vc-ignores' or `project-vc-name'." :type '(repeat string) :version "29.1" - :package-version '(project . "0.9.0") - :safe (lambda (val) (and (listp val) (cl-every #'stringp val)))) + :package-version '(project . "0.9.0")) +;;;###autoload(put 'project-vc-extra-root-markers 'safe-local-variable (lambda (val) (and (listp val) (cl-every #'stringp val)))) ;; FIXME: Using the current approach, major modes are supposed to set ;; this variable to a buffer-local value. So we don't have access to @@ -1453,8 +1453,8 @@ Used by `project-kill-buffers'." :type 'boolean :version "29.1" :group 'project - :package-version '(project . "0.8.2") - :safe #'booleanp) + :package-version '(project . "0.8.2")) +;;;###autoload(put 'project-kill-buffers-display-buffer-list 'safe-local-variable #'booleanp) (defun project--buffer-check (buf conditions) "Check if buffer BUF matches any element of the list CONDITIONS. From 9f5249d5c8d193fc59d09b9003d26d1ed0884f2c Mon Sep 17 00:00:00 2001 From: Po Lu Date: Fri, 26 May 2023 08:41:31 +0800 Subject: [PATCH 38/54] Disable cairo-xcb support by default * INSTALL (--with-cairo-xcb): Document new option. * configure.ac (USE_CAIRO_XCB): Implement new option. --- INSTALL | 6 ++++++ configure.ac | 17 +++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/INSTALL b/INSTALL index 344ae39f464..2bb8df52dc9 100644 --- a/INSTALL +++ b/INSTALL @@ -394,6 +394,12 @@ typical 32-bit host, Emacs integers have 62 bits instead of 30. Use --with-cairo to compile Emacs with Cairo drawing. +Use --with-cairo-xcb to also utilize the Cairo XCB backend on systems +where it is available. While such a configuration is moderately +faster when running over X connections with high latency, it is likely +to crash when a new frame is created on a display connection opened +after a display connection is closed. + Use --with-modules to build Emacs with support for dynamic modules. This needs a C compiler that supports '__attribute__ ((cleanup (...)))', as in GCC 3.4 and later. diff --git a/configure.ac b/configure.ac index 2c80d4cc9aa..7ded5289d31 100644 --- a/configure.ac +++ b/configure.ac @@ -459,6 +459,7 @@ OPTION_DEFAULT_ON([sqlite3],[don't compile with sqlite3 support]) OPTION_DEFAULT_ON([lcms2],[don't compile with Little CMS support]) OPTION_DEFAULT_ON([libsystemd],[don't compile with libsystemd support]) OPTION_DEFAULT_ON([cairo],[don't compile with Cairo drawing]) +OPTION_DEFAULT_OFF([cairo-xcb], [use XCB surfaces for Cairo support]) OPTION_DEFAULT_ON([xml2],[don't compile with XML parsing support]) OPTION_DEFAULT_OFF([imagemagick],[compile with ImageMagick image support]) OPTION_DEFAULT_ON([native-image-api], [don't use native image APIs (GDI+ on Windows)]) @@ -3607,14 +3608,14 @@ if test "${HAVE_X11}" = "yes"; then CAIRO_MODULE="cairo >= $CAIRO_REQUIRED" EMACS_CHECK_MODULES([CAIRO], [$CAIRO_MODULE]) if test $HAVE_CAIRO = yes; then - CAIRO_XCB_MODULE="cairo-xcb >= $CAIRO_REQUIRED" - EMACS_CHECK_MODULES([CAIRO_XCB], [$CAIRO_XCB_MODULE]) - if test $HAVE_CAIRO_XCB = yes; then - CAIRO_CFLAGS="$CAIRO_CFLAGS $CAIRO_XCB_CFLAGS" - CAIRO_LIBS="$CAIRO_LIBS $CAIRO_XCB_LIBS" - AC_DEFINE([USE_CAIRO_XCB], [1], - [Define to 1 if cairo XCB surfaces are available.]) - fi + AS_IF([test "x$with_cairo_xcb" = "xyes"], [ + CAIRO_XCB_MODULE="cairo-xcb >= $CAIRO_REQUIRED" + EMACS_CHECK_MODULES([CAIRO_XCB], [$CAIRO_XCB_MODULE]) + AS_IF([test "x$HAVE_CAIRO_XCB" = "xyes"], [ + CAIRO_CFLAGS="$CAIRO_CFLAGS $CAIRO_XCB_CFLAGS" + CAIRO_LIBS="$CAIRO_LIBS $CAIRO_XCB_LIBS" + AC_DEFINE([USE_CAIRO_XCB], [1], + [Define to 1 if cairo XCB surfaces are available.])])]) AC_DEFINE([USE_CAIRO], [1], [Define to 1 if using cairo.]) CFLAGS="$CFLAGS $CAIRO_CFLAGS" LIBS="$LIBS $CAIRO_LIBS" From 42052686752e399e778d33401dd621afbac0071d Mon Sep 17 00:00:00 2001 From: Po Lu Date: Fri, 26 May 2023 08:43:18 +0800 Subject: [PATCH 39/54] Don't mark selection request events * src/pgtkterm.c (mark_pgtkterm): Prevent crash by not marking selection request events, which don't have Lisp_Object members. --- src/pgtkterm.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/pgtkterm.c b/src/pgtkterm.c index c00e13550bd..f4b05ef9903 100644 --- a/src/pgtkterm.c +++ b/src/pgtkterm.c @@ -376,6 +376,13 @@ mark_pgtkterm (void) for (i = 0; i < n; i++) { union buffered_input_event *ev = &evq->q[i]; + + /* Selection requests don't have Lisp object members. */ + + if (ev->ie.kind == SELECTION_REQUEST_EVENT + || ev->ie.kind == SELECTION_CLEAR_EVENT) + continue; + mark_object (ev->ie.x); mark_object (ev->ie.y); mark_object (ev->ie.frame_or_window); From c0d7447e9dc14cca9a71c8cd4a84573c22108662 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 26 May 2023 10:07:34 +0300 Subject: [PATCH 40/54] ; * etc/NEWS: Describe the Cairo XCB option. (Bug#63589) --- etc/NEWS | 46 ++++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index a29e0a08cfc..a3457d70340 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -91,24 +91,6 @@ available, and includes support for animated WebP images. To disable WebP support, use the '--without-webp' configure flag. Image specifiers can now use ':type webp'. -+++ -** Emacs has been ported to the Haiku operating system. -The configuration process should automatically detect and build for -Haiku. There is also an optional window-system port to Haiku, which -can be enabled by configuring Emacs with the option '--with-be-app', -which will require the Haiku Application Kit development headers and a -C++ compiler to be present on your system. If Emacs is not built with -the option '--with-be-app', the resulting Emacs will only run in -text-mode terminals. - -To enable Cairo support, ensure that the Cairo and FreeType -development files are present on your system, and configure Emacs with -'--with-be-cairo'. - -Unlike X, there is no compile-time option to enable or disable -double-buffering; it is always enabled. To disable it, change the -frame parameter 'inhibit-double-buffering' instead. - --- ** Emacs now installs the ".pdmp" file using a unique fingerprint in the name. The file is typically installed using a file name akin to @@ -126,6 +108,16 @@ option '--without-xinput2' to disable this support. '(featurep 'xinput2)' can be used to test for the presence of XInput 2 support from Lisp programs. +--- +** Emacs can now be optionally built with the Cairo XCB backend. +Configure Emacs with the '--with-cairo-xcb' option to use the Cairo +XCB backend; the default is not to use it. This backend makes Emacs +moderately faster when running over X connections with high latency, +but is currently known to crash when Emacs repeatedly closes and opens +a display connection to the same terminal; this could happen, for +example, if you repeatedly visit files via emacsclient in a single +client frame, each time deleting the frame with 'C-x C-c'. + +++ ** Emacs now supports being built with pure GTK. To use this option, make sure the GTK 3 (version 3.22.23 or later) and @@ -144,6 +136,24 @@ automatically switch to text-mode interface (thus emulating '-nw') if it cannot determine the default display; it will instead complain and ask you to invoke it with the explicit '-nw' option. ++++ +** Emacs has been ported to the Haiku operating system. +The configuration process should automatically detect and build for +Haiku. There is also an optional window-system port to Haiku, which +can be enabled by configuring Emacs with the option '--with-be-app', +which will require the Haiku Application Kit development headers and a +C++ compiler to be present on your system. If Emacs is not built with +the option '--with-be-app', the resulting Emacs will only run in +text-mode terminals. + +To enable Cairo support, ensure that the Cairo and FreeType +development files are present on your system, and configure Emacs with +'--with-be-cairo'. + +Unlike X, there is no compile-time option to enable or disable +double-buffering; it is always enabled. To disable it, change the +frame parameter 'inhibit-double-buffering' instead. + --- ** Emacs no longer reduces the size of the Japanese dictionary. Building Emacs includes generation of a Japanese dictionary, which is From 40a758f5ceb3d46fa3669e2471db1a45a08f3a23 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 26 May 2023 11:09:14 +0300 Subject: [PATCH 41/54] ; Minor fixes in documentation of recently-changed VC commands * lisp/vc/vc.el (vc-print-branch-log, vc-create-branch) (vc-create-tag, vc-retrieve-tag, vc-switch-branch): Doc fixes. * lisp/vc/vc-hooks.el (vc-menu-map): Minor wording change in :help text. * doc/emacs/maintaining.texi (VC Change Log, Creating Branches): Minor wording and markup changes. --- doc/emacs/maintaining.texi | 7 +++--- lisp/vc/vc-hooks.el | 2 +- lisp/vc/vc.el | 49 ++++++++++++++++++++++++++++---------- 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi index 06f44a88aab..246e335cfe7 100644 --- a/doc/emacs/maintaining.texi +++ b/doc/emacs/maintaining.texi @@ -1071,8 +1071,9 @@ revision at point. A second @key{RET} hides it again. @findex vc-print-branch-log @kbd{C-x v b l @var{branch-name} @key{RET}} (@code{vc-print-branch-log}) displays a @file{*vc-change-log*} buffer showing the history of the -version-controlled directory tree like @code{vc-print-root-log} does, -but in another branch provided as an argument. +version-controlled directory tree, like @code{vc-print-root-log} does, +but it shows the history of a branch other than the current one; it +prompts for the branch whose history to display. @kindex C-x v I @kindex C-x v O @@ -1690,7 +1691,7 @@ and so on, depending on the number of existing branches at that point. @findex vc-create-branch This procedure will not work for distributed version control systems like git or Mercurial. For those systems you should use the command -@code{vc-create-branch} (@kbd{C-x v b c @var{branch-name} @key{RET}}) +@code{vc-create-branch} (@w{@kbd{C-x v b c @var{branch-name} @key{RET}}}) instead. To create a new branch at an older revision (one that is no longer diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el index b559a776c09..00a7659209e 100644 --- a/lisp/vc/vc-hooks.el +++ b/lisp/vc/vc-hooks.el @@ -899,7 +899,7 @@ In the latter case, VC mode is deactivated for this buffer." :help "Create version tag")) (bindings--define-key map [vc-print-branch-log] '(menu-item "Show Branch History..." vc-print-branch-log - :help "List the change log for a branch")) + :help "List the change log for another branch")) (bindings--define-key map [vc-switch-branch] '(menu-item "Switch Branch..." vc-switch-branch :help "Switch to another branch")) diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index ba981545085..1144a23f317 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -2504,9 +2504,13 @@ Otherwise, return nil." (defun vc-create-tag (dir name branchp) "Descending recursively from DIR, make a tag called NAME. For each registered file, the working revision becomes part of -the named configuration. If the prefix argument BRANCHP is -given, the tag is made as a new branch and the files are -checked out in that new branch." +the configuration identified by the tag. +If BRANCHP is non-nil (interactively, the prefix argument), the +tag NAME is a new branch, and the files are checked out and +updated to reflect their revisions on that branch. +In interactive use, DIR is `default-directory' for repository-granular +VCSes (all the modern decentralized VCSes belong to this group), +otherwise the command will prompt for DIR." (interactive (let ((granularity (vc-call-backend (vc-responsible-backend default-directory) @@ -2529,9 +2533,23 @@ checked out in that new branch." ;;;###autoload (defun vc-create-branch (dir name) - "Descending recursively from DIR, make a branch called NAME. -After a new branch is made, the files are checked out in that new branch. -Uses `vc-create-tag' with the non-nil arg `branchp'." + "Make a branch called NAME in directory DIR. +After making the new branch, check out the branch, i.e. update the +files in the tree to their revisions on the branch. + +Interactively, prompt for the NAME of the branch. + +With VCSes that maintain version information per file, this command also +prompts for the directory DIR whose files, recursively, will be tagged +with the NAME of new branch. For VCSes that maintain version +information for the entire repository (all the modern decentralized +VCSes belong to this group), DIR is always the `default-directory'. + +Finally, this command might prompt for the branch or tag from which to +start (\"fork\") the new branch, with completion candidates including +all the known branches and tags in the repository. + +This command invokes `vc-create-tag' with the non-nil BRANCHP argument." (interactive (let ((granularity (vc-call-backend (vc-responsible-backend default-directory) @@ -2545,17 +2563,17 @@ Uses `vc-create-tag' with the non-nil arg `branchp'." ;;;###autoload (defun vc-retrieve-tag (dir name &optional branchp) - "For each file in or below DIR, retrieve their tagged version NAME. + "For each file in or below DIR, retrieve their version identified by tag NAME. NAME can name a branch, in which case this command will switch to the named branch in the directory DIR. Interactively, prompt for DIR only for VCS that works at file level; -otherwise use the repository root of the current buffer. +otherwise use the root directory of the current buffer's VC tree. If NAME is empty, it refers to the latest revisions of the current branch. If locking is used for the files in DIR, then there must not be any locked files at or below DIR (but if NAME is empty, locked files are allowed and simply skipped). -If the prefix argument BRANCHP is given, switch the branch -and check out the files in that branch. +If BRANCHP is non-nil (interactively, the prefix argument), switch to the +branch and check out and update the files to their version on that branch. This function runs the hook `vc-retrieve-tag-hook' when finished." (interactive (let* ((granularity @@ -2596,7 +2614,12 @@ This function runs the hook `vc-retrieve-tag-hook' when finished." ;;;###autoload (defun vc-switch-branch (dir name) "Switch to the branch NAME in the directory DIR. -If NAME is empty, it refers to the latest revisions of the current branch. +If NAME is empty, it refers to the latest revision of the current branch. +Interactively, prompt for DIR only for VCS that works at file level; +otherwise use the root directory of the current buffer's VC tree. +Interactively, prompt for the NAME of the branch. +After switching to the branch, check out and update the files to their +version on that branch. Uses `vc-retrieve-tag' with the non-nil arg `branchp'." (interactive (let* ((granularity @@ -2851,8 +2874,8 @@ with its diffs (if the underlying VCS backend supports that)." ;;;###autoload (defun vc-print-branch-log (branch) - "Show the change log for BRANCH in a window. -The command prompts for the branch to log." + "Show the change log for BRANCH in another window. +The command prompts for the branch whose change log to show." (interactive (let* ((backend (vc-responsible-backend default-directory)) (rootdir (vc-call-backend backend 'root default-directory))) From f535c0e49d5e629e60eabe9097b9c674783f9674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= Date: Thu, 25 May 2023 22:28:25 +0200 Subject: [PATCH 42/54] Handle #@00 in new reader in a compatible way (bug#63722) This was a regression from Emacs 28. * src/lread.c (skip_lazy_string, read0): Make #@00 read as nil, which is a quirk from the old reader that we preserve for compatibility. * test/src/lread-tests.el (lread-skip-to-eof): Verify it. Reported by Richard Newton. --- src/lread.c | 17 +++++++++++------ test/src/lread-tests.el | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/src/lread.c b/src/lread.c index 342d367d985..29321263af3 100644 --- a/src/lread.c +++ b/src/lread.c @@ -3400,8 +3400,9 @@ read_bool_vector (Lisp_Object readcharfun) } /* Skip (and optionally remember) a lazily-loaded string - preceded by "#@". */ -static void + preceded by "#@". Return true if this was a normal skip, + false if we read #@00 (which skips to EOF). */ +static bool skip_lazy_string (Lisp_Object readcharfun) { ptrdiff_t nskip = 0; @@ -3427,9 +3428,9 @@ skip_lazy_string (Lisp_Object readcharfun) digits++; if (digits == 2 && nskip == 0) { - /* #@00 means "skip to end" */ + /* #@00 means "read nil and skip to end" */ skip_dyn_eof (readcharfun); - return; + return false; } } @@ -3476,6 +3477,8 @@ skip_lazy_string (Lisp_Object readcharfun) else /* Skip that many bytes. */ skip_dyn_bytes (readcharfun, nskip); + + return true; } /* Given a lazy-loaded string designator VAL, return the actual string. @@ -3933,8 +3936,10 @@ read0 (Lisp_Object readcharfun, bool locate_syms) /* #@NUMBER is used to skip NUMBER following bytes. That's used in .elc files to skip over doc strings and function definitions that can be loaded lazily. */ - skip_lazy_string (readcharfun); - goto read_obj; + if (skip_lazy_string (readcharfun)) + goto read_obj; + obj = Qnil; /* #@00 skips to EOF and yields nil. */ + break; case '$': /* #$ -- reference to lazy-loaded string */ diff --git a/test/src/lread-tests.el b/test/src/lread-tests.el index 459a06a39b6..7d885abf364 100644 --- a/test/src/lread-tests.el +++ b/test/src/lread-tests.el @@ -339,4 +339,20 @@ literals (Bug#20852)." (should (byte-code-function-p f)) (should (equal (aref f 4) "My little\ndoc string\nhere")))))) +(ert-deftest lread-skip-to-eof () + ;; Check the special #@00 syntax that, for compatibility, reads as + ;; nil while absorbing the remainder of the input. + (with-temp-buffer + (insert "#@00 and the rest\n" + "should be ignored) entirely\n") + (goto-char (point-min)) + (should (equal (read (current-buffer)) nil)) + (should (eobp)) + ;; Add an unbalanced bracket to the beginning and try again; + ;; we should get an error. + (goto-char (point-min)) + (insert "( ") + (goto-char (point-min)) + (should-error (read (current-buffer)) :type 'end-of-file))) + ;;; lread-tests.el ends here From f35648ba0c0f7dac78ea1d1aaad80471238b7ace Mon Sep 17 00:00:00 2001 From: Eshel Yaron Date: Mon, 15 May 2023 21:04:21 +0300 Subject: [PATCH 43/54] Add customization options for dictionary-search Allow users to customize 'dictionary-search' via several new customization options. * lisp/net/dictionary.el (dictionary-define-word) (dictionary-match-word, dictionary-completing-read-word) (dictionary-dictionaries, dictionary-completing-read-dictionary) (dictionary-display-definition-in-help-buffer): New functions. (dictionary-read-word-prompt) (dictionary-display-definition-function) (dictionary-read-word-function) (dictionary-read-dictionary-function) (dictionary-search-interface): New user options. (dictionary-search): Use them. (dictionary-read-dictionary-default) (dictionary-read-word-default): New functions, extracted from 'dictionary-search'. * etc/NEWS: Announce. --- etc/NEWS | 45 +++++++++ lisp/net/dictionary.el | 203 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 233 insertions(+), 15 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index 7729dbc79fa..07fc2fab774 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -342,6 +342,51 @@ The new Rmail commands 'rmail-mailing-list-post', 'rmail-mailing-list-archive allow to, respectively, post to, unsubscribe from, request help about, and browse the archives, of the mailing list from which the current email message was delivered. + +** Dictionary + +--- +*** New user option 'dictionary-search-interface'. +Controls how the 'dictionary-search' command prompts for and displays +dictionary definitions. Customize this user option to 'help' to have +'dictionary-search' display definitions in a *Help* buffer and provide +dictionary-based minibuffer completion for word selection. + +--- +*** New user option 'dictionary-read-word-prompt'. +This allows the user to customize the prompt that is used by +'dictionary-search' when asking for a word to search in the +dictionary. + +--- +*** New user option 'dictionary-display-definition-function'. +This allows the user to customize the way in which 'dictionary-search' +displays word definitions. If non-nil, this user option should be set +to a function that displays a word definition obtained from a +dictionary server. The new function +'dictionary-display-definition-in-help-buffer' can be used to display +the definition in a *Help* buffer, instead of the default *Dictionary* +buffer. + +--- +*** New user option 'dictionary-read-word-function'. +This allows the user to customize the way in which 'dictionary-search' +prompts for a word to search in the dictionary. This user option +should be set to a function that lets the user select a word and +returns it as a string. The new function +'dictionary-completing-read-word' can be used to prompt with +completion based on dictionary matches. + +--- +*** New user option 'dictionary-read-dictionary-function'. +This allows the user to customize the way in which 'dictionary-search' +prompts for a dictionary to search in. This user option should be set +to a function that lets the user select a dictionary and returns its +name as a string. The new function +'dictionary-completing-read-dictionary' can be used to prompt with +completion based on dictionaries that the server supports. + + * New Modes and Packages in Emacs 30.1 diff --git a/lisp/net/dictionary.el b/lisp/net/dictionary.el index ba65225692a..8d81b3ec9d8 100644 --- a/lisp/net/dictionary.el +++ b/lisp/net/dictionary.el @@ -38,6 +38,8 @@ (require 'custom) (require 'dictionary-connection) (require 'button) +(require 'help-mode) +(require 'external-completion) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Stuff for customizing. @@ -247,6 +249,65 @@ is utf-8" ))) :version "28.1") +(defcustom dictionary-read-word-prompt "Search word" + "Prompt string to use when prompting for a word." + :type 'string + :version "30.1") + +(defcustom dictionary-display-definition-function nil + "Function to use for displaying dictionary definitions. +It is called with three string arguments: the word being defined, +the dictionary name, and the full definition." + :type '(choice (const :tag "Dictionary buffer" nil) + (const :tag "Help buffer" + dictionary-display-definition-in-help-buffer) + (function :tag "Custom function")) + :version "30.1") + +(defcustom dictionary-read-word-function #'dictionary-read-word-default + "Function to use for prompting for a word. +It is called with one string argument, the name of the dictionary to use, and +must return a string." + :type '(choice (const :tag "Default" dictionary-read-word-default) + (const :tag "Dictionary-based completion" + dictionary-completing-read-word) + (function :tag "Custom function")) + :version "30.1") + +(defcustom dictionary-read-dictionary-function + #'dictionary-read-dictionary-default + "Function to use for prompting for a dictionary. +It is called with no arguments and must return a string." + :type '(choice (const :tag "Default" dictionary-read-dictionary-default) + (const :tag "Choose among server-provided dictionaries" + dictionary-completing-read-dictionary) + (function :tag "Custom function")) + :version "30.1") + +(defcustom dictionary-search-interface nil + "Controls how `dictionary-search' prompts for words and displays definitions. + +When set to `help', `dictionary-search' displays definitions in a *Help* buffer, +and provides completion for word selection based on dictionary matches. + +Otherwise, `dictionary-search' displays definitions in a *Dictionary* buffer." + :type '(choice (const :tag "Dictionary buffer" nil) + (const :tag "Help buffer" help)) + :set (lambda (symbol value) + (let ((vals (pcase value + ('help '(dictionary-display-definition-in-help-buffer + dictionary-completing-read-word + dictionary-completing-read-dictionary)) + (_ '(nil + dictionary-read-word-default + dictionary-read-dictionary-default))))) + (seq-setq (dictionary-display-definition-function + dictionary-read-word-function + dictionary-read-dictionary-function) + vals)) + (set-default-toplevel-value symbol value)) + :version "30.1") + (defface dictionary-word-definition-face '((((supports (:family "DejaVu Serif"))) (:family "DejaVu Serif")) @@ -366,6 +427,8 @@ is utf-8" '() "History list of searched word.") +(defvar dictionary--last-match nil) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Basic function providing startup actions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1139,6 +1202,20 @@ If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." ((car (get-char-property (point) 'data))) (t (current-word t)))) +(defun dictionary-read-dictionary-default () + "Prompt for a dictionary name." + (read-string (if dictionary-default-dictionary + (format "Dictionary (%s): " + dictionary-default-dictionary) + "Dictionary: ") + nil nil dictionary-default-dictionary)) + +(defun dictionary-read-word-default (_dictionary) + "Prompt for a word to search in the dictionary." + (let ((default (dictionary-search-default))) + (read-string (format-prompt dictionary-read-word-prompt default) + nil 'dictionary-word-history default))) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; User callable commands ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1149,23 +1226,22 @@ If PATTERN is omitted, it defaults to \"[ \\f\\t\\n\\r\\v]+\"." It presents the selection or word at point as default input and allows editing it." (interactive - (list (let ((default (dictionary-search-default))) - (read-string (format-prompt "Search word" default) - nil 'dictionary-word-history default)) - (if current-prefix-arg - (read-string (if dictionary-default-dictionary - (format "Dictionary (%s): " dictionary-default-dictionary) - "Dictionary: ") - nil nil dictionary-default-dictionary) - dictionary-default-dictionary))) - - ;; if called by pressing the button - (unless word - (setq word (read-string "Search word: " nil 'dictionary-word-history))) - ;; just in case non-interactively called + (let ((dict + (if current-prefix-arg + (funcall dictionary-read-dictionary-function) + dictionary-default-dictionary))) + (list (funcall dictionary-read-word-function dict) dict))) (unless dictionary (setq dictionary dictionary-default-dictionary)) - (dictionary-new-search (cons word dictionary))) + (if dictionary-display-definition-function + (if-let ((definition (dictionary-define-word word dictionary))) + (funcall dictionary-display-definition-function word dictionary definition) + (user-error "No definition found for \"%s\"" word)) + ;; if called by pressing the button + (unless word + (setq word (read-string "Search word: " nil 'dictionary-word-history))) + ;; just in case non-interactively called + (dictionary-new-search (cons word dictionary)))) ;;;###autoload (defun dictionary-lookup-definition () @@ -1386,5 +1462,102 @@ the word at mouse click." 'dictionary-separator)) menu) +(defun dictionary-define-word (word dictionary) + "Return the definition of WORD in DICTIONARY, or nil if not found." + (dictionary-send-command + (format "define %s \"%s\"" dictionary word)) + (when (and (= (read (dictionary-read-reply)) 150) + (= (read (dictionary-read-reply)) 151)) + (dictionary-read-answer))) + +(defun dictionary-match-word (word &rest _) + "Return dictionary matches for WORD as a list of strings. +Further arguments are currently ignored." + (unless (string-empty-p word) + (if (string= (car dictionary--last-match) word) + (cdr dictionary--last-match) + (dictionary-send-command + (format "match %s %s \"%s\"" + dictionary-default-dictionary + dictionary-default-strategy + word)) + (when (and (= (read (dictionary-read-reply)) 152)) + (with-temp-buffer + (insert (dictionary-read-answer)) + (goto-char (point-min)) + (let ((result nil)) + (while (not (eobp)) + (search-forward " " nil t) + (push (read (current-buffer)) result) + (search-forward "\n" nil t)) + (setq result (reverse result)) + (setq dictionary--last-match (cons word result)) + result)))))) + +(defun dictionary-completing-read-word (dictionary) + "Prompt for a word with completion based on matches in DICTIONARY." + (let* ((completion-ignore-case t) + (dictionary-default-dictionary dictionary) + (word-at-point (thing-at-point 'word t)) + (default (dictionary-match-word word-at-point))) + (completing-read (format-prompt dictionary-read-word-prompt default) + (external-completion-table 'dictionary-definition + #'dictionary-match-word) + nil t nil 'dictionary-word-history default t))) + +(defun dictionary-dictionaries () + "Return the list of dictionaries the server supports." + (dictionary-send-command "show db") + (when (and (= (read (dictionary-read-reply)) 110)) + (with-temp-buffer + (insert (dictionary-read-answer)) + (goto-char (point-min)) + (let ((result '(("!" . "First matching dictionary") + ("*" . "All dictionaries")))) + (while (not (eobp)) + (push (cons (buffer-substring + (search-forward "\n" nil t) + (1- (search-forward " " nil t))) + (read (current-buffer))) + result)) + (reverse result))))) + +(defun dictionary-completing-read-dictionary () + "Prompt for a dictionary the server supports." + (let* ((dicts (dictionary-dictionaries)) + (len (apply #'max (mapcar #'length (mapcar #'car dicts)))) + (completion-extra-properties + (list :annotation-function + (lambda (key) + (concat (make-string (1+ (- len (length key))) ?\s) + (alist-get key dicts nil nil #'string=)))))) + (completing-read (format-prompt "Select dictionary" + dictionary-default-dictionary) + dicts nil t nil nil dictionary-default-dictionary))) + +(define-button-type 'help-word + :supertype 'help-xref + 'help-function 'dictionary-search + 'help-echo "mouse-2, RET: describe this word") + +(defun dictionary-display-definition-in-help-buffer (word dictionary definition) + "Display DEFINITION, the definition of WORD in DICTIONARY." + (let ((help-buffer-under-preparation t)) + (help-setup-xref (list #'dictionary-search word dictionary) + (called-interactively-p 'interactive)) + (with-help-window (help-buffer) + (with-current-buffer (help-buffer) + (insert definition) + ;; Buttonize references to other definitions. These appear as + ;; words enclosed with curly braces. + (goto-char (point-min)) + (while (re-search-forward (rx "{" + (group-n 1 (* (not (any ?})))) + "}") + nil t) + (help-xref-button 1 'help-word + (match-string 1) + dictionary)))))) + (provide 'dictionary) ;;; dictionary.el ends here From b6b384023a97185486ed4d69fb18bcd2d3cf8049 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 26 May 2023 12:23:19 +0300 Subject: [PATCH 44/54] Fix cancellation of Wdired * lisp/wdired.el (wdired-abort-changes): Call 'dired-revert'. Patch by Stephen Berman . (Bug#63676) --- lisp/wdired.el | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lisp/wdired.el b/lisp/wdired.el index 5572dcb32f3..9952da71078 100644 --- a/lisp/wdired.el +++ b/lisp/wdired.el @@ -470,6 +470,9 @@ non-nil means return old filename." (insert wdired--old-content) (goto-char wdired--old-point)) (wdired-change-to-dired-mode) + ;; Make sure the display is in synch, and all the variables are set + ;; correctly. + (dired-revert) (set-buffer-modified-p nil) (setq buffer-undo-list nil) (message "Changes aborted")) From f42de74ebea14de1d8a69d2b79489814ab711883 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 26 May 2023 12:30:40 +0300 Subject: [PATCH 45/54] ; * src/lread.c (read0, skip_lazy_string): Fix commentary wording. --- src/lread.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lread.c b/src/lread.c index 29321263af3..f8ee4e63e23 100644 --- a/src/lread.c +++ b/src/lread.c @@ -3401,7 +3401,7 @@ read_bool_vector (Lisp_Object readcharfun) /* Skip (and optionally remember) a lazily-loaded string preceded by "#@". Return true if this was a normal skip, - false if we read #@00 (which skips to EOF). */ + false if we read #@00 (which skips to EOB). */ static bool skip_lazy_string (Lisp_Object readcharfun) { @@ -3938,7 +3938,7 @@ read0 (Lisp_Object readcharfun, bool locate_syms) and function definitions that can be loaded lazily. */ if (skip_lazy_string (readcharfun)) goto read_obj; - obj = Qnil; /* #@00 skips to EOF and yields nil. */ + obj = Qnil; /* #@00 skips to EOB and yields nil. */ break; case '$': From b7b82ecb2b4c2ce33c11e5388b692cd403ab55e6 Mon Sep 17 00:00:00 2001 From: kobarity Date: Wed, 24 May 2023 22:01:12 +0900 Subject: [PATCH 46/54] Fix python-info-docstring-p * lisp/progmodes/python.el (python-info-docstring-p): Stop using python-rx string-delimiter. * test/lisp/progmodes/python-tests.el (python-font-lock-escape-sequence-bytes-newline) (python-font-lock-escape-sequence-hex-octal) (python-font-lock-escape-sequence-unicode) (python-font-lock-raw-escape-sequence): Mark as expected failures until another bug in 'python-info-docstring-p' is corrected. (python-info-docstring-p-7): New test. (Bug#63622) --- lisp/progmodes/python.el | 7 ++----- test/lisp/progmodes/python-tests.el | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 6fc05b246a6..032a17c52ff 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -6018,8 +6018,7 @@ point's current `syntax-ppss'." (let ((counter 1) (indentation (current-indentation)) (backward-sexp-point) - (re (concat "[uU]?[rR]?" - (python-rx string-delimiter)))) + (re "[uU]?[rR]?[\"']")) (when (and (not (python-info-assignment-statement-p)) (looking-at-p re) @@ -6040,9 +6039,7 @@ point's current `syntax-ppss'." backward-sexp-point)) (setq last-backward-sexp-point backward-sexp-point)) - (looking-at-p - (concat "[uU]?[rR]?" - (python-rx string-delimiter)))))) + (looking-at-p re)))) ;; Previous sexp was a string, restore point. (goto-char backward-sexp-point) (cl-incf counter)) diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el index 50153e66da5..cbaf5b698bd 100644 --- a/test/lisp/progmodes/python-tests.el +++ b/test/lisp/progmodes/python-tests.el @@ -729,6 +729,7 @@ u\"\\n\"" (845 . font-lock-string-face) (886)))) (ert-deftest python-font-lock-escape-sequence-bytes-newline () + :expected-result :failed (python-tests-assert-faces "b'\\n' b\"\\n\"" @@ -741,6 +742,7 @@ b\"\\n\"" (11 . font-lock-doc-face)))) (ert-deftest python-font-lock-escape-sequence-hex-octal () + :expected-result :failed (python-tests-assert-faces "b'\\x12 \\777 \\1\\23' '\\x12 \\777 \\1\\23'" @@ -761,6 +763,7 @@ b\"\\n\"" (36 . font-lock-doc-face)))) (ert-deftest python-font-lock-escape-sequence-unicode () + :expected-result :failed (python-tests-assert-faces "b'\\u1234 \\U00010348 \\N{Plus-Minus Sign}' '\\u1234 \\U00010348 \\N{Plus-Minus Sign}'" @@ -775,6 +778,7 @@ b\"\\n\"" (80 . font-lock-doc-face)))) (ert-deftest python-font-lock-raw-escape-sequence () + :expected-result :failed (python-tests-assert-faces "rb'\\x12 \123 \\n' r'\\x12 \123 \\n \\u1234 \\U00010348 \\N{Plus-Minus Sign}'" @@ -6598,6 +6602,18 @@ class Class: (python-tests-look-at "'''Not a method docstring.'''") (should (not (python-info-docstring-p))))) +(ert-deftest python-info-docstring-p-7 () + "Test string in a dictionary." + (python-tests-with-temp-buffer + " +{'Not a docstring': 1} +'Also not a docstring' +" + (python-tests-look-at "Not a docstring") + (should-not (python-info-docstring-p)) + (python-tests-look-at "Also not a docstring") + (should-not (python-info-docstring-p)))) + (ert-deftest python-info-triple-quoted-string-p-1 () "Test triple quoted string." (python-tests-with-temp-buffer From aa5158630e7113a67ae804d4253911028cb8f984 Mon Sep 17 00:00:00 2001 From: kobarity Date: Wed, 24 May 2023 22:06:51 +0900 Subject: [PATCH 47/54] Use 'font-lock-extend-region-functions' in python-mode * lisp/progmodes/python.el (python-font-lock-extend-region): Change arguments and return value for 'font-lock-extend-region-functions'. (python-mode): Change from 'font-lock-extend-after-change-region-function' to 'font-lock-extend-region-functions'. (Bug#63622) --- lisp/progmodes/python.el | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 032a17c52ff..adaeacc2ec1 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -869,18 +869,22 @@ decorators, exceptions, and assignments.") Which one will be chosen depends on the value of `font-lock-maximum-decoration'.") -(defun python-font-lock-extend-region (beg end _old-len) - "Extend font-lock region given by BEG and END to statement boundaries." - (save-excursion - (save-match-data - (goto-char beg) - (python-nav-beginning-of-statement) - (setq beg (point)) - (goto-char end) - (python-nav-end-of-statement) - (setq end (point)) - (cons beg end)))) - +(defvar font-lock-beg) +(defvar font-lock-end) +(defun python-font-lock-extend-region () + "Extend font-lock region to statement boundaries." + (let ((beg font-lock-beg) + (end font-lock-end)) + (goto-char beg) + (python-nav-beginning-of-statement) + (beginning-of-line) + (when (< (point) beg) + (setq font-lock-beg (point))) + (goto-char end) + (python-nav-end-of-statement) + (when (< end (point)) + (setq font-lock-end (point))) + (or (/= beg font-lock-beg) (/= end font-lock-end)))) (defconst python-syntax-propertize-function (syntax-propertize-rules @@ -6704,9 +6708,9 @@ implementations: `python-mode' and `python-ts-mode'." `(,python-font-lock-keywords nil nil nil nil (font-lock-syntactic-face-function - . python-font-lock-syntactic-face-function) - (font-lock-extend-after-change-region-function - . python-font-lock-extend-region))) + . python-font-lock-syntactic-face-function))) + (add-hook 'font-lock-extend-region-functions + #'python-font-lock-extend-region nil t) (setq-local syntax-propertize-function python-syntax-propertize-function) (setq-local imenu-create-index-function From d6f717cd1dc373707440011a1552b78de2654bba Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 26 May 2023 13:20:56 +0300 Subject: [PATCH 48/54] Fix emacsclient when there are irrecoverable file-visiting errors * lisp/server.el (server-process-filter, server-return-error): Display the error message to be sent to the client as a regular message, to give the user the opportunity to see it. Delete the terminal immediately after sending the error message to the client, to make sure the terminal's modes are restored. (Bug#63629) --- lisp/server.el | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lisp/server.el b/lisp/server.el index 608e5df3a5b..c3325e5a24c 100644 --- a/lisp/server.el +++ b/lisp/server.el @@ -1143,8 +1143,18 @@ The following commands are accepted by the client: (process-put proc :authenticated t) (server-log "Authentication successful" proc)) (server-log "Authentication failed" proc) + ;; Display the error as a message and give the user time to see + ;; it, in case the error written by emacsclient to stderr is not + ;; visible for some reason. + (message "Authentication failed") + (sit-for 2) (server-send-string proc (concat "-error " (server-quote-arg "Authentication failed"))) + (unless (eq system-type 'windows-nt) + (let ((terminal (process-get proc 'terminal))) + ;; Only delete the terminal if it is non-nil. + (when (and terminal (eq (terminal-live-p terminal) t)) + (delete-terminal terminal)))) ;; Before calling `delete-process', give emacsclient time to ;; receive the error string and shut down on its own. (sit-for 1) @@ -1462,10 +1472,20 @@ The following commands are accepted by the client: (defun server-return-error (proc err) (ignore-errors + ;; Display the error as a message and give the user time to see + ;; it, in case the error written by emacsclient to stderr is not + ;; visible for some reason. + (message (error-message-string err)) + (sit-for 2) (server-send-string proc (concat "-error " (server-quote-arg (error-message-string err)))) (server-log (error-message-string err) proc) + (unless (eq system-type 'windows-nt) + (let ((terminal (process-get proc 'terminal))) + ;; Only delete the terminal if it is non-nil. + (when (and terminal (eq (terminal-live-p terminal) t)) + (delete-terminal terminal)))) ;; Before calling `delete-process', give emacsclient time to ;; receive the error string and shut down on its own. (sit-for 5) From 54ac1165bc3f6012201689b7f23d7edba2926f6d Mon Sep 17 00:00:00 2001 From: Spencer Baugh Date: Wed, 19 Apr 2023 17:44:54 -0400 Subject: [PATCH 49/54] Support setting PAGER=cat in comint.el (bug#62958) Paging can be undesirable in comint-derived commands such as async-shell-command and M-x shell. It is a frequent footgun for new Emacs users when they try to run commands which start a pager in such modes. Simply adding (setenv "PAGER" "cat") globally is not correct, since that will break modes like term, which support paging quite well. It's only and exactly the comint-derived modes which don't need paging. * lisp/comint.el (comint-pager): Add. (bug#62958) (comint-exec-1): Use comint-pager to set PAGER. --- lisp/comint.el | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/lisp/comint.el b/lisp/comint.el index 77973ab76de..718a972a582 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -258,6 +258,35 @@ to set this in a mode hook, rather than customize the default value." file) :group 'comint) +(defcustom comint-pager nil + "If non-nil, the program to use for pagination of program output. + +Some programs produce large amounts of output, and have provision for +pagination of their output through a filter program, commonly known as +a \"pager\". The pager limits the amount of output produced and +allows the user to interactively browse the output one page at a time. +Some programs paginate their output by default, by always starting a +pager. The program they use as the pager is specified by the +environment variable PAGER; if that variable is not defined, they use +some fixed default, such as \"less\". + +The interactive browsing aspects of pagination are not needed, and get +in the way, when the output of the program is directed to an Emacs +buffer, so in those cases pagination might need to be disabled. +Disabling pagination means that some programs will produce large +amounts of output, but most such programs have other ways to limit +their output, such as additional arguments or Emacs interfaces. +To disable pagination, this variable's value should be a string that +names a program, such as \"cat\", which passes through all of the +output without any filtering or delays. Comint will then set the +PAGER variable to name that program, when it invokes external +programs." + :version "30.1" + :type '(choice (const :tag "Use default PAGER" nil) + (const :tag "Don't do paging (PAGER=cat)" "cat") + (string :tag "Program name or absolute path of pager")) + :group 'comint) + (defvar comint-input-ring-file-prefix nil "The prefix to skip when parsing the input ring file. This is useful in Zsh when the extended_history option is on.") @@ -865,6 +894,10 @@ series of processes in the same Comint buffer. The hook (nconc (comint-term-environment) (list (format "INSIDE_EMACS=%s,comint" emacs-version)) + (when comint-pager + (if (stringp comint-pager) + (list (format "PAGER=%s" comint-pager)) + (error "comint-pager should be a string: %s" comint-pager))) process-environment)) (default-directory (if (file-accessible-directory-p default-directory) From ef778f5143f04c6b5c0561ad38c04a08bb2cb701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= Date: Fri, 26 May 2023 12:28:15 +0200 Subject: [PATCH 50/54] Add more function declarations * lisp/subr.el (buffer-narrowed-p, sha1, match-substitute-replacement) (version-to-list, version<, version<=, version=) (function-get, subregexp-context-p, split-string) (combine-and-quote-strings, split-string-and-unquote) (replace-regexp-in-string, syntax-after) (string-trim-left, string-trim): * lisp/emacs-lisp/subr-x.el (hash-table-empty-p, hash-table-keys) (hash-table-values, string-glyph-split) (string-clean-whitespace, string-fill, string-limit) (string-pixel-width): * lisp/env.el (substitute-env-vars, substitute-env-in-file-name) (setenv-internal): * lisp/emacs-lisp/rx.el (rx-to-string): * lisp/emacs-lisp/regexp-opt.el (regexp-opt-depth) (regexp-opt-charset): Add appropriate declarations: pure, side-effect-free, and/or important-return-value. --- lisp/emacs-lisp/regexp-opt.el | 2 ++ lisp/emacs-lisp/rx.el | 1 + lisp/emacs-lisp/subr-x.el | 9 +++++++++ lisp/env.el | 3 +++ lisp/subr.el | 18 +++++++++++++++++- 5 files changed, 32 insertions(+), 1 deletion(-) diff --git a/lisp/emacs-lisp/regexp-opt.el b/lisp/emacs-lisp/regexp-opt.el index fd9fbbe25a4..39325a3c35e 100644 --- a/lisp/emacs-lisp/regexp-opt.el +++ b/lisp/emacs-lisp/regexp-opt.el @@ -154,6 +154,7 @@ usually more efficient than that of a simplified version: "Return the depth of REGEXP. This means the number of non-shy regexp grouping constructs \(parenthesized expressions) in REGEXP." + (declare (pure t) (side-effect-free t)) (save-match-data ;; Hack to signal an error if REGEXP does not have balanced parentheses. (string-match regexp "") @@ -270,6 +271,7 @@ Merges keywords to avoid backtracking in Emacs's regexp matcher." CHARS should be a list of characters. If CHARS is the empty list, the return value is a regexp that never matches anything." + (declare (pure t) (side-effect-free t)) ;; The basic idea is to find character ranges. Also we take care in the ;; position of character set meta characters in the character set regexp. ;; diff --git a/lisp/emacs-lisp/rx.el b/lisp/emacs-lisp/rx.el index 46f61c26bc4..e82490ffee5 100644 --- a/lisp/emacs-lisp/rx.el +++ b/lisp/emacs-lisp/rx.el @@ -1144,6 +1144,7 @@ If NO-GROUP is non-nil, don't bracket the result in a non-capturing group. For extending the `rx' notation in FORM, use `rx-define' or `rx-let-eval'." + (declare (important-return-value t)) (let* ((item (rx--translate form)) (exprs (if no-group (car item) diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el index 947390b3de3..9e906930b92 100644 --- a/lisp/emacs-lisp/subr-x.el +++ b/lisp/emacs-lisp/subr-x.el @@ -81,18 +81,22 @@ Note how the single `-' got converted into a list before threading." (declare (indent 0) (debug thread-first)) `(internal--thread-argument nil ,@forms)) + (defsubst hash-table-empty-p (hash-table) "Check whether HASH-TABLE is empty (has 0 elements)." + (declare (side-effect-free t)) (zerop (hash-table-count hash-table))) (defsubst hash-table-keys (hash-table) "Return a list of keys in HASH-TABLE." + (declare (side-effect-free t)) (let ((keys nil)) (maphash (lambda (k _) (push k keys)) hash-table) keys)) (defsubst hash-table-values (hash-table) "Return a list of values in HASH-TABLE." + (declare (side-effect-free t)) (let ((values nil)) (maphash (lambda (_ v) (push v values)) hash-table) values)) @@ -149,6 +153,7 @@ carriage return." All sequences of whitespaces in STRING are collapsed into a single space character, and leading/trailing whitespace is removed." + (declare (important-return-value t)) (let ((blank "[[:blank:]\r\n]+")) (string-trim (replace-regexp-in-string blank " " string t t) blank blank))) @@ -158,6 +163,7 @@ removed." Wrapping is done where there is whitespace. If there are individual words in STRING that are longer than LENGTH, the result will have lines that are longer than LENGTH." + (declare (important-return-value t)) (with-temp-buffer (insert string) (goto-char (point-min)) @@ -189,6 +195,7 @@ coding system that doesn't specify a BOM, like `utf-16le' or `utf-16be'. When shortening strings for display purposes, `truncate-string-to-width' is almost always a better alternative than this function." + (declare (important-return-value t)) (unless (natnump length) (signal 'wrong-type-argument (list 'natnump length))) (if coding-system @@ -324,6 +331,7 @@ as the new values of the bound variables in the recursive invocation." ;;;###autoload (defun string-pixel-width (string) "Return the width of STRING in pixels." + (declare (important-return-value t)) (if (zerop (length string)) 0 ;; Keeping a work buffer around is more efficient than creating a @@ -344,6 +352,7 @@ This takes into account combining characters and grapheme clusters: if compositions are enabled, each sequence of characters composed on display into a single grapheme cluster is treated as a single indivisible unit." + (declare (side-effect-free t)) (let ((result nil) (start 0) comp) diff --git a/lisp/env.el b/lisp/env.el index faafcb6250f..281934af054 100644 --- a/lisp/env.el +++ b/lisp/env.el @@ -76,6 +76,7 @@ If it is non-nil and not a function, references to undefined variables are left unchanged. Use `$$' to insert a single dollar sign." + (declare (important-return-value t)) (let ((start 0)) (while (string-match env--substitute-vars-regexp string start) (cond ((match-beginning 1) @@ -94,6 +95,7 @@ Use `$$' to insert a single dollar sign." string)) (defun substitute-env-in-file-name (filename) + (declare (important-return-value t)) (substitute-env-vars filename ;; How 'bout we lookup other tables than the env? ;; E.g. we could accept bookmark names as well! @@ -104,6 +106,7 @@ Use `$$' to insert a single dollar sign." (defun setenv-internal (env variable value keep-empty) "Set VARIABLE to VALUE in ENV, adding empty entries if KEEP-EMPTY. Changes ENV by side-effect, and returns its new value." + (declare (important-return-value t)) (let ((pattern (concat "\\`" (regexp-quote variable) "\\(=\\|\\'\\)")) (case-fold-search nil) (scan env) diff --git a/lisp/subr.el b/lisp/subr.el index 7670143c7cd..95d3bc03544 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -4006,6 +4006,7 @@ See also `locate-user-emacs-file'.") (defsubst buffer-narrowed-p () "Return non-nil if the current buffer is narrowed." + (declare (side-effect-free t)) (/= (- (point-max) (point-min)) (buffer-size))) (defmacro with-restriction (start end &rest rest) @@ -4132,7 +4133,7 @@ See Info node `(elisp)Security Considerations'. If the optional POSIX argument is non-nil, ARGUMENT is quoted according to POSIX shell quoting rules, regardless of the system's shell." -(cond + (cond ((and (not posix) (eq system-type 'ms-dos)) ;; Quote using double quotes, but escape any existing quotes in ;; the argument with backslashes. @@ -4264,6 +4265,7 @@ string; otherwise returna 40-character string. Note that SHA-1 is not collision resistant and should not be used for anything security-related. See `secure-hash' for alternatives." + (declare (side-effect-free t)) (secure-hash 'sha1 object start end binary)) (defun function-get (f prop &optional autoload) @@ -4271,6 +4273,7 @@ alternatives." If AUTOLOAD is non-nil and F is autoloaded, try to load it in the hope that it will set PROP. If AUTOLOAD is `macro', do it only if it's an autoloaded macro." + (declare (important-return-value t)) (let ((val nil)) (while (and (symbolp f) (null (setq val (get f prop))) @@ -5226,6 +5229,7 @@ In other words, all back-references in the form `\\&' and `\\N' are substituted with actual strings matched by the last search. Optional FIXEDCASE, LITERAL, STRING and SUBEXP have the same meaning as for `replace-match'." + (declare (side-effect-free t)) (let ((match (match-string 0 string))) (save-match-data (match-data--translate (- (match-beginning 0))) @@ -5287,6 +5291,7 @@ A non-subregexp context is for example within brackets, or within a repetition bounds operator `\\=\\{...\\}', or right after a `\\'. If START is non-nil, it should be a position in REGEXP, smaller than POS, and known to be in a subregexp context." + (declare (important-return-value t)) ;; Here's one possible implementation, with the great benefit that it ;; reuses the regexp-matcher's own parser, so it understands all the ;; details of the syntax. A disadvantage is that it needs to match the @@ -5368,6 +5373,7 @@ case that you wish to retain zero-length substrings when splitting on whitespace, use `(split-string STRING split-string-default-separators)'. Modifies the match data; use `save-match-data' if necessary." + (declare (important-return-value t)) (let* ((keep-nulls (not (if separators omit-nulls t))) (rexp (or separators split-string-default-separators)) (start 0) @@ -5425,6 +5431,7 @@ Only some SEPARATORs will work properly. Note that this is not intended to protect STRINGS from interpretation by shells, use `shell-quote-argument' for that." + (declare (important-return-value t)) (let* ((sep (or separator " ")) (re (concat "[\\\"]" "\\|" (regexp-quote sep)))) (mapconcat @@ -5439,6 +5446,7 @@ interpretation by shells, use `shell-quote-argument' for that." It understands Emacs Lisp quoting within STRING, such that (split-string-and-unquote (combine-and-quote-strings strs)) == strs The SEPARATOR regexp defaults to \"\\s-+\"." + (declare (important-return-value t)) (let ((sep (or separator "\\s-+")) (i (string-search "\"" string))) (if (null i) @@ -5506,6 +5514,7 @@ To replace only the first match (if any), make REGEXP match up to \\\\=' and replace a sub-expression, e.g. (replace-regexp-in-string \"\\\\(foo\\\\).*\\\\\\='\" \"bar\" \" foo foo\" nil nil 1) => \" bar foo\"" + (declare (important-return-value t)) ;; To avoid excessive consing from multiple matches in long strings, ;; don't just call `replace-match' continually. Walk down the @@ -5861,6 +5870,7 @@ from `standard-syntax-table' otherwise." (defun syntax-after (pos) "Return the raw syntax descriptor for the char after POS. If POS is outside the buffer's accessible portion, return nil." + (declare (important-return-value t)) (unless (or (< pos (point-min)) (>= pos (point-max))) (let ((st (if parse-sexp-lookup-properties (get-char-property pos 'syntax-table)))) @@ -6675,6 +6685,7 @@ Examples of version conversion: \"22.8beta3\" (22 8 -2 3) See documentation for `version-separator' and `version-regexp-alist'." + (declare (side-effect-free t)) (unless (stringp ver) (error "Version must be a string")) ;; Change .x.y to 0.x.y @@ -6805,6 +6816,7 @@ etc. That is, the trailing \".0\"s are insignificant. Also, version string \"1\" is higher (newer) than \"1pre\", which is higher than \"1beta\", which is higher than \"1alpha\", which is higher than \"1snapshot\". Also, \"-GIT\", \"-CVS\" and \"-NNN\" are treated as snapshot versions." + (declare (side-effect-free t)) (version-list-< (version-to-list v1) (version-to-list v2))) (defun version<= (v1 v2) @@ -6815,6 +6827,7 @@ etc. That is, the trailing \".0\"s are insignificant. Also, version string \"1\" is higher (newer) than \"1pre\", which is higher than \"1beta\", which is higher than \"1alpha\", which is higher than \"1snapshot\". Also, \"-GIT\", \"-CVS\" and \"-NNN\" are treated as snapshot versions." + (declare (side-effect-free t)) (version-list-<= (version-to-list v1) (version-to-list v2))) (defun version= (v1 v2) @@ -6825,6 +6838,7 @@ etc. That is, the trailing \".0\"s are insignificant. Also, version string \"1\" is higher (newer) than \"1pre\", which is higher than \"1beta\", which is higher than \"1alpha\", which is higher than \"1snapshot\". Also, \"-GIT\", \"-CVS\" and \"-NNN\" are treated as snapshot versions." + (declare (side-effect-free t)) (version-list-= (version-to-list v1) (version-to-list v2))) (defvar package--builtin-versions @@ -6947,6 +6961,7 @@ returned list are in the same order as in TREE. "Trim STRING of leading string matching REGEXP. REGEXP defaults to \"[ \\t\\n\\r]+\"." + (declare (important-return-value t)) (if (string-match (if regexp (concat "\\`\\(?:" regexp "\\)") "\\`[ \t\n\r]+") @@ -6969,6 +6984,7 @@ REGEXP defaults to \"[ \\t\\n\\r]+\"." "Trim STRING of leading and trailing strings matching TRIM-LEFT and TRIM-RIGHT. TRIM-LEFT and TRIM-RIGHT default to \"[ \\t\\n\\r]+\"." + (declare (important-return-value t)) (string-trim-left (string-trim-right string trim-right) trim-left)) ;; The initial anchoring is for better performance in searching matches. From 1eb5faa26113afe5895955a74594e3d7cf6ffe98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mattias=20Engdeg=C3=A5rd?= Date: Fri, 26 May 2023 14:33:12 +0200 Subject: [PATCH 51/54] ; * lisp/progmodes/project.el: avoid warning in loaddefs --- lisp/progmodes/project.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index 6054f7dc689..41a5c976629 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -468,7 +468,7 @@ variables, such as `project-vc-ignores' or `project-vc-name'." :type '(repeat string) :version "29.1" :package-version '(project . "0.9.0")) -;;;###autoload(put 'project-vc-extra-root-markers 'safe-local-variable (lambda (val) (and (listp val) (cl-every #'stringp val)))) +;;;###autoload(put 'project-vc-extra-root-markers 'safe-local-variable (lambda (val) (and (listp val) (not (memq nil (mapcar #'stringp val)))))) ;; FIXME: Using the current approach, major modes are supposed to set ;; this variable to a buffer-local value. So we don't have access to From bb7605c087006b714236165f88341545355d3673 Mon Sep 17 00:00:00 2001 From: Alan Mackenzie Date: Fri, 26 May 2023 14:32:07 +0000 Subject: [PATCH 52/54] Fontify Java constructor names and arglists This fixes bug#63328. * lisp/progmodes/cc-engine.el (c-forward-decl-or-cast-1): New variable got-stmt-block. After scanning an arglist, set got-arglist to t. When we have as yet no identifier, got-arglist, and scan an open brace, test the "type" for being the name of the enclosing class. (c-directly-in-class-called-p): Test the two names for equality, not merely one being the head of the other. --- lisp/progmodes/cc-engine.el | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index d21e082d0b6..66cfd3dee9e 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -10636,6 +10636,10 @@ This function might do hidden buffer changes." got-parens ;; True if there is a terminated argument list. got-arglist + ;; True when `got-arglist' and the token after the end of the + ;; arglist is an opening brace. Used only when we have a + ;; suspected typeless function name. + got-stmt-block ;; True if there is an identifier in the declarator. got-identifier ;; True if we find a number where an identifier was expected. @@ -10788,6 +10792,10 @@ This function might do hidden buffer changes." (setq got-arglist t)) t) (when (cond + ((and (eq (char-after) ?\() + (c-safe (c-forward-sexp 1) t)) + (when (eq (char-before) ?\)) + (setq got-arglist t))) ((save-match-data (looking-at "\\s(")) (c-safe (c-forward-sexp 1) t)) ((save-match-data @@ -10802,6 +10810,11 @@ This function might do hidden buffer changes." (setq got-suffix-after-parens (match-beginning 0))) (setq got-suffix t)))) + ((and got-arglist + (eq (char-after) ?{)) + (setq got-stmt-block t) + nil) + (t ;; No suffix matched. We might have matched the ;; identifier as a type and the open paren of a @@ -10870,9 +10883,17 @@ This function might do hidden buffer changes." (not (memq context '(arglist decl)))) (or (and new-style-auto (looking-at c-auto-ops-re)) - (and (or maybe-typeless backup-maybe-typeless) - (not got-prefix) - at-type))) + (and (not got-prefix) + at-type + (or maybe-typeless backup-maybe-typeless + ;; Do we have a (typeless) constructor? + (and got-stmt-block + (save-excursion + (goto-char type-start) + (and + (looking-at c-identifier-key) + (c-directly-in-class-called-p + (match-string 0))))))))) ;; Have found no identifier but `c-typeless-decl-kwds' has ;; matched so we know we're inside a declaration. The ;; preceding type must be the identifier instead. @@ -12554,7 +12575,8 @@ comment at the start of cc-engine.el for more info." (looking-at c-class-key)) (goto-char (match-end 1)) (c-forward-syntactic-ws) - (looking-at name)))))) + (and (looking-at c-identifier-key) + (string= (match-string 0) name))))))) (defun c-search-uplist-for-classkey (paren-state) ;; Check if the closest containing paren sexp is a declaration From 321ed8ebae8f84e0f8ae6cf2012f0f8830d9fda9 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Fri, 26 May 2023 11:18:49 -0400 Subject: [PATCH 53/54] * lisp/emacs-lisp/package.el (package-buffer-info): Fix last change The code that follows expects point to be at/near the end of the buffer. --- lisp/emacs-lisp/package.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index e906c73ecab..69595601bc8 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -1199,7 +1199,7 @@ boundaries." ;; the earliest in version 31.1. The idea is to phase out the ;; requirement for a "footer line" without unduly impacting users ;; on earlier Emacs versions. See Bug#26490 for more details. - (unless (search-forward (concat ";;; " file-name ".el ends here") nil t) + (unless (search-forward (concat ";;; " file-name ".el ends here") nil 'move) (lwarn '(package package-format) :warning "Package lacks a terminating comment")) ;; Try to include a trailing newline. From e77e986a9b7d735c0e39198c8b80a34a29005fc5 Mon Sep 17 00:00:00 2001 From: Stefan Monnier Date: Fri, 26 May 2023 12:23:59 -0400 Subject: [PATCH 54/54] package-tests.el: Add test for last change * test/lisp/emacs-lisp/package-tests.el (package-test-desc-from-buffer): Make sure the absence of the terminating comment does not matter. --- test/lisp/emacs-lisp/package-tests.el | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/test/lisp/emacs-lisp/package-tests.el b/test/lisp/emacs-lisp/package-tests.el index 0016fb586b7..113b4ec12a8 100644 --- a/test/lisp/emacs-lisp/package-tests.el +++ b/test/lisp/emacs-lisp/package-tests.el @@ -219,9 +219,14 @@ Must called from within a `tar-mode' buffer." (ert-deftest package-test-desc-from-buffer () "Parse an elisp buffer to get a `package-desc' object." - (with-package-test (:basedir (ert-resource-directory) :file "simple-single-1.3.el") - (should (package-test--compatible-p - (package-buffer-info) simple-single-desc 'kind))) + (with-package-test (:basedir (ert-resource-directory) + :file "simple-single-1.3.el") + (let ((pi (package-buffer-info))) + (should (package-test--compatible-p pi simple-single-desc 'kind)) + ;; The terminating line is not mandatory any more. + (re-search-forward "^;;; .* ends here") + (delete-region (match-beginning 0) (point-max)) + (should (equal (package-buffer-info) pi)))) (with-package-test (:basedir (ert-resource-directory) :file "simple-depend-1.0.el") (should (package-test--compatible-p (package-buffer-info) simple-depend-desc 'kind)))