commit 0467b756aaef713fb948e2746e1333a9d86e2e7e (HEAD, refs/remotes/origin/master) Author: Po Lu Date: Thu Jun 6 09:15:50 2024 +0800 * java/AndroidManifest.xml.in: Revert portions of last change. diff --git a/java/AndroidManifest.xml.in b/java/AndroidManifest.xml.in index 644f154b53b..f3bab2c1b76 100644 --- a/java/AndroidManifest.xml.in +++ b/java/AndroidManifest.xml.in @@ -224,7 +224,6 @@ along with GNU Emacs. If not, see . --> android:taskAffinity="emacs.primary_frame" android:windowSoftInputMode="adjustResize" android:exported="true" - android:stateNotNeeded="true" android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|locale|fontScale"> @@ -282,7 +281,6 @@ along with GNU Emacs. If not, see . --> android:windowSoftInputMode="adjustResize" android:exported="true" android:maxRecents="50" - android:stateNotNeeded="true" android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|locale|fontScale"/> Date: Tue Jun 4 10:42:35 2024 -0700 Select correct frame after enabling erc-nickbar-mode * lisp/erc/erc-speedbar.el (erc-speedbar--ensure): Re-select frame originally selected when earlier calling `speedbar-frame-mode'. Do this because `speedbar-frame' may become the new selected frame when multiple visible frames exist. (erc-nickbar-disable): Don't expect the mode to have been enabled previously. diff --git a/lisp/erc/erc-speedbar.el b/lisp/erc/erc-speedbar.el index d4f91bb363a..3e8c110a31b 100644 --- a/lisp/erc/erc-speedbar.el +++ b/lisp/erc/erc-speedbar.el @@ -517,7 +517,8 @@ associated with an ERC session." '(visibility . nil) '(no-other-frame . t) speedbar-frame-parameters)) - (speedbar-after-create-hook #'erc-speedbar--emulate-sidebar)) + (speedbar-after-create-hook #'erc-speedbar--emulate-sidebar) + (original-frame (selected-frame))) (erc-install-speedbar-variables) ;; Run before toggling mode to prevent timer from being ;; created twice. @@ -527,8 +528,8 @@ associated with an ERC session." ;; the frame with `window-main-window' will be raised and ;; steal focus if you switch away from Emacs in the meantime. (let ((frame speedbar-frame)) - (cl-assert (not (eq speedbar-frame (selected-frame)))) - (select-frame (setq speedbar-frame (selected-frame))) + (cl-assert (not (eq speedbar-frame original-frame))) + (select-frame (setq speedbar-frame original-frame)) (delete-frame frame)) ;; Allow deleting (our) `speedbar-frame' with the mouse. (with-current-buffer speedbar-buffer @@ -602,19 +603,21 @@ For controlling whether the speedbar window is selectable with (setq erc-track--switch-fallback-blockers (remove '(derived-mode . speedbar-mode) erc-track--switch-fallback-blockers))) - (cl-assert speedbar-buffer) - ;; Close associated windows and stop updating but leave timer. - (dolist (window (get-buffer-window-list speedbar-buffer nil t)) - (unless (frame-root-window-p window) - (when erc-speedbar--hidden-speedbar-frame - (cl-assert (not (eq (window-frame window) - erc-speedbar--hidden-speedbar-frame)))) - (delete-window window))) - (with-current-buffer speedbar-buffer - (setq speedbar-update-flag nil) - (speedbar-set-mode-line-format) - (unless (eq erc--module-toggle-prefix-arg most-negative-fixnum) - (dframe-close-frame))))) + ;; `speedbar-buffer' may be nil if the mode was never enabled, such + ;; as when disabling the module through Customize after startup. + (when speedbar-buffer + ;; Close associated windows and stop updating but leave timer. + (dolist (window (get-buffer-window-list speedbar-buffer nil t)) + (unless (frame-root-window-p window) + (when erc-speedbar--hidden-speedbar-frame + (cl-assert (not (eq (window-frame window) + erc-speedbar--hidden-speedbar-frame)))) + (delete-window window))) + (with-current-buffer speedbar-buffer + (setq speedbar-update-flag nil) + (speedbar-set-mode-line-format) + (unless (eq erc--module-toggle-prefix-arg most-negative-fixnum) + (dframe-close-frame)))))) (defun erc-speedbar--get-timers () (cl-remove #'dframe-timer-fn timer-idle-list commit 50b134c4dc828485705a0a5b5a884379ff25bb15 Author: F. Jason Park Date: Tue May 28 00:32:13 2024 -0700 Don't recurse in erc-server-delayed-check-reconnect * lisp/erc/erc-backend.el (erc-server-delayed-check-reconnect): Run `reschedule' function on a timer to avoid growing the stack when calling `delete-process'. * lisp/erc/erc-common.el (erc--favor-changed-reverted-modules-state): Fix `pcase' condition so that changing an option to its standard value does not earn a "STANDARD" label in Customize if that value differs from the saved one. * lisp/erc/erc.el (erc-open-socks-tls-stream): Reword doc string. * test/lisp/erc/erc-tests.el (erc--with-dependent-type-match) (erc--with-dependent-type-match): Remove useless tests (bug#71178). * test/lisp/erc/resources/base/reconnect/unexpected-disconnect.eld: Await phantom EOFs and PINGs to somewhat account for a race that can result in a failure when running the suite in parallel with -jN. * test/lisp/erc/resources/erc-scenarios-common.el (erc-scenarios-common--print-trace): Set `debug-on-error' to t so that errors in timers always trigger test failures. ;; * test/lisp/erc/resources/base/assoc/reconplay/foonet.eld: ;; Timeouts. ;; * test/lisp/erc/resources/base/upstream-reconnect/soju-barnet.eld: ;; Timeouts. ;; * test/lisp/erc/resources/base/mask-target-routing/foonet.eld: ;; Timeouts. ;; * test/lisp/erc/resources/join/network-id/barnet.eld: Timeout. diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index a1f84ee5165..e2b7c0b6f48 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -885,7 +885,7 @@ Expect BUFFER to be the server buffer for the current connection." (time-convert nil 'integer)))) ((or "connection broken by remote peer\n" (rx bot "failed")) - (funcall reschedule proc))))) + (run-at-time nil nil reschedule proc))))) (filter (lambda (proc _) (delete-process proc) (with-current-buffer buffer diff --git a/lisp/erc/erc-common.el b/lisp/erc/erc-common.el index 4ba7990ab98..3577e697515 100644 --- a/lisp/erc/erc-common.el +++ b/lisp/erc/erc-common.el @@ -191,7 +191,7 @@ widget runs its set function.") "Be more nuanced in displaying Custom state of `erc-modules'. When `customized-value' differs from `saved-value', allow widget to behave normally and show \"SET for current session\", as -though `customize-set-variable' or similar had been applied. +though `customize-set-variable' or similar has been applied. However, when `customized-value' and `standard-value' match but differ from `saved-value', prefer showing \"CHANGED outside Customize\" to prevent the widget from seeing a `standard' @@ -207,7 +207,7 @@ instead of a `set' state, which precludes any actual saving." (funcall (get 'erc-modules 'custom-set) 'erc-modules (funcall op (erc--normalize-module-symbol name) erc-modules)) (when (equal (pcase (get 'erc-modules 'saved-value) - (`((quote ,saved) saved))) + (`((quote ,saved)) saved)) erc-modules) (customize-mark-as-set 'erc-modules))) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index b375df1edb6..2deaedae955 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -2951,15 +2951,16 @@ PARAMETERS should be a sequence of keywords and values, per (defun erc-open-socks-tls-stream (name buffer host service &rest parameters) "Connect to an IRC server via SOCKS proxy over TLS. -Defer to the `socks' and `gnutls' libraries to make the actual -connection and perform TLS negotiation. Expect SERVICE to be a -TLS port number and that the plist PARAMETERS contains a -`:client-certificate' pair when necessary. Otherwise, assume the -arguments NAME, BUFFER, and HOST to be acceptable to -`open-network-stream' and that users know to check out -`erc-server-connect-function' and Info node `(erc) SOCKS' for -more info, including an important example of how to \"wrap\" this -function with SOCKS credentials." +Perform the duties required of an `erc-server-connect-function' +implementer, and return a network process. Defer to the `socks' +and `gnutls' libraries to make the connection and handle TLS +negotiation. Expect SERVICE to be a TLS port number and +PARAMETERS to be a possibly empty plist containing items like a +`:client-certificate' pair. Pass NAME, BUFFER, and HOST directly +to `open-network-stream'. Beyond that, operate as described in +Info node `(erc) SOCKS', and expect users to \"wrap\" this +function with `let'-bound credentials when necessary, as shown in +the example." (require 'gnutls) (require 'socks) (let ((proc (socks-open-network-stream name buffer host service)) diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index f393402fe81..f4cff06f942 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -164,15 +164,6 @@ (advice-remove 'buffer-local-value 'erc-with-server-buffer))) -(ert-deftest erc--with-dependent-type-match () - (should (equal (macroexpand-1 - '(erc--with-dependent-type-match (repeat face) erc-match)) - '(backquote-list* - 'repeat :match (lambda (w v) - (require 'erc-match) - (widget-editable-list-match w v)) - '(face))))) - (ert-deftest erc--doarray () (let ((array "abcdefg") out) @@ -1269,23 +1260,6 @@ (should-not (erc--valid-local-channel-p "#chan")) (should (erc--valid-local-channel-p "&local"))))) -;; FIXME remove this because it serves no purpose. See bug#71178. -(ert-deftest erc--restore-initialize-priors () - (unless (>= emacs-major-version 28) - (ert-skip "Lisp nesting exceeds `max-lisp-eval-depth'")) - (should (pcase (macroexpand-1 '(erc--restore-initialize-priors erc-my-mode - foo (ignore 1 2 3) - bar #'spam - baz nil)) - (`(let* ((,p (or erc--server-reconnecting erc--target-priors)) - (,q (and ,p (alist-get 'erc-my-mode ,p)))) - (unless (local-variable-if-set-p 'erc-my-mode) - (error "Not a local minor mode var: %s" 'erc-my-mode)) - (setq foo (if ,q (alist-get 'foo ,p) (ignore 1 2 3)) - bar (if ,q (alist-get 'bar ,p) #'spam) - baz (if ,q (alist-get 'baz ,p) nil))) - t)))) - (ert-deftest erc--target-from-string () (should (equal (erc--target-from-string "#chan") #s(erc--target-channel "#chan" \#chan nil))) diff --git a/test/lisp/erc/resources/base/assoc/reconplay/foonet.eld b/test/lisp/erc/resources/base/assoc/reconplay/foonet.eld index 15bcca2a623..78697d6f2c9 100644 --- a/test/lisp/erc/resources/base/assoc/reconplay/foonet.eld +++ b/test/lisp/erc/resources/base/assoc/reconplay/foonet.eld @@ -33,7 +33,7 @@ (0.0 ":***!znc@znc.in PRIVMSG #chan :Playback Complete.") (0.0 ":irc.foonet.org 305 tester :You are no longer marked as being away")) -((mode 3 "MODE #chan") +((mode-chan 10 "MODE #chan") (1.0 ":irc.foonet.org 324 tester #chan +nt") (0.0 ":irc.foonet.org 329 tester #chan 1623816901") (0.1 ":alice!~u@mw6kegwt77kwe.irc PRIVMSG #chan :bob: At thy good heart's oppression.") diff --git a/test/lisp/erc/resources/base/mask-target-routing/foonet.eld b/test/lisp/erc/resources/base/mask-target-routing/foonet.eld index 796d5566b65..7b5796129f7 100644 --- a/test/lisp/erc/resources/base/mask-target-routing/foonet.eld +++ b/test/lisp/erc/resources/base/mask-target-routing/foonet.eld @@ -17,7 +17,7 @@ (0 ":irc.foonet.org 266 tester 4 4 :Current global users 4, max 4") (0 ":irc.foonet.org 422 tester :MOTD File is missing")) -((mode-user 1.2 "MODE tester +i") +((mode-user 10 "MODE tester +i") ;; No mode answer (0 ":irc.znc.in 306 tester :You have been marked as being away") (0 ":tester!~u@gq7yjr7gsu7nn.irc JOIN #foo") diff --git a/test/lisp/erc/resources/base/reconnect/unexpected-disconnect.eld b/test/lisp/erc/resources/base/reconnect/unexpected-disconnect.eld index 386d0f4b085..80903f94155 100644 --- a/test/lisp/erc/resources/base/reconnect/unexpected-disconnect.eld +++ b/test/lisp/erc/resources/base/reconnect/unexpected-disconnect.eld @@ -1,4 +1,8 @@ ;; -*- mode: lisp-data; -*- + +((~eof 60 EOF)) +((~ping 60 "PING")) + ((nick 10 "NICK tester")) ((user 10 "USER user 0 * :tester") (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester") diff --git a/test/lisp/erc/resources/base/upstream-reconnect/soju-barnet.eld b/test/lisp/erc/resources/base/upstream-reconnect/soju-barnet.eld index 3711eb8f8e6..4b7db5a91b1 100644 --- a/test/lisp/erc/resources/base/upstream-reconnect/soju-barnet.eld +++ b/test/lisp/erc/resources/base/upstream-reconnect/soju-barnet.eld @@ -10,13 +10,13 @@ (0.22 ":soju.im 221 tester +Zi") (0.00 ":soju.im 422 tester :Use /motd to read the message of the day")) -((mode 5 "MODE tester +i") +((mode-tester 5 "MODE tester +i") (0.00 ":tester!tester@10.0.2.100 JOIN #chan") (0.06 ":soju.im 353 tester = #chan :tester @mike joe") (0.01 ":soju.im 366 tester #chan :End of /NAMES list") (0.23 ":irc.barnet.org 221 tester +Zi")) -((mode 5 "MODE #chan") +((mode-chan-a 5 "MODE #chan") (0.00 ":soju.im 324 tester #chan +tn") (0.01 ":soju.im 329 tester #chan 1652878846") (0.01 ":joe!~u@6d9pasqcqwb2s.irc PRIVMSG #chan :mike: There is five in the first show.") @@ -49,7 +49,7 @@ ;; Server-initialed join (0.01 ":tester!tester@10.0.2.100 JOIN #chan")) -((mode 5 "MODE #chan") +((mode-chan-b 5 "MODE #chan") (0.22 ":soju.im 353 tester = #chan :@mike joe tester") (0.00 ":soju.im 366 tester #chan :End of /NAMES list") (0.00 ":soju.im 324 tester #chan +nt") diff --git a/test/lisp/erc/resources/erc-scenarios-common.el b/test/lisp/erc/resources/erc-scenarios-common.el index c7d5c9d6677..0dc82c98d5f 100644 --- a/test/lisp/erc/resources/erc-scenarios-common.el +++ b/test/lisp/erc/resources/erc-scenarios-common.el @@ -144,6 +144,7 @@ (quit . ,(erc-quit/part-reason-default)) (erc-version . ,erc-version))) (erc-modules (copy-sequence erc-modules)) + (debug-on-error t) (inhibit-interaction noninteractive) (auth-source-do-cache nil) (timer-list (copy-sequence timer-list)) diff --git a/test/lisp/erc/resources/join/network-id/barnet.eld b/test/lisp/erc/resources/join/network-id/barnet.eld index ad6a7c820a9..3d13c7a6296 100644 --- a/test/lisp/erc/resources/join/network-id/barnet.eld +++ b/test/lisp/erc/resources/join/network-id/barnet.eld @@ -1,5 +1,5 @@ ;; -*- mode: lisp-data; -*- -((pass 2 "PASS :barnet:changeme")) +((pass 10 "PASS :barnet:changeme")) ((nick 2 "NICK tester")) ((user 1 "USER user 0 * :tester") (0 ":irc.barnet.org 001 tester :Welcome to the barnet IRC Network tester") commit ec8c0b0d0d8a6b8804fa3e6619242ec6db32fd19 Author: Juri Linkov Date: Wed Jun 5 20:07:28 2024 +0300 Allow multi-level outlines in tabulated-list-groups used by list-buffers * lisp/emacs-lisp/tabulated-list.el (tabulated-list-groups) (tabulated-list-groups-categorize, tabulated-list-groups-sort) (tabulated-list-groups-flatten): New functions (bug#70150). * lisp/buff-menu.el (Buffer-menu-group-by): Change type from a function to a list of functions. (list-buffers--refresh): Use the function 'tabulated-list-groups' where :path-function uses a list of functions from 'Buffer-menu-group-by', and :sort-function is hard-coded to sort groups by name. (Buffer-menu-group-by-mode, Buffer-menu-group-by-root): Remove prefix "*". diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el index d59c5b6cf21..d83bf2249e6 100644 --- a/lisp/buff-menu.el +++ b/lisp/buff-menu.el @@ -96,8 +96,10 @@ as it is by default." :version "22.1") (defcustom Buffer-menu-group-by nil - "If non-nil, a function to call to divide buffer-menu buffers into groups. -This function is called with one argument: a list of entries in the same + "If non-nil, functions to call to divide buffer-menu buffers into groups. +When customized to a list of functions, then each function defines +the group name at each nested level of multiple levels. +Each function is called with one argument: a list of entries in the same format as in `tabulated-list-entries', and should return a list in the format suitable for `tabulated-list-groups'. Also, when this variable is non-nil, `outline-minor-mode' is enabled in the Buffer Menu and you @@ -107,11 +109,13 @@ The default options can group by a mode, and by a root directory of a project or just `default-directory'. If this is nil, buffers are not divided into groups." :type '(choice (const :tag "No grouping" nil) - (const :tag "Group by mode" - Buffer-menu-group-by-mode) - (const :tag "Group by project root or directory" - Buffer-menu-group-by-root) - (function :tag "Custom function")) + (repeat :tag "Group by" + (choice + (const :tag "Group by project root or directory" + Buffer-menu-group-by-root) + (const :tag "Group by mode" + Buffer-menu-group-by-mode) + (function :tag "Custom function")))) :group 'Buffer-menu :version "30.1") @@ -775,10 +779,17 @@ See more at `Buffer-menu-filter-predicate'." '("File" 1 t))) (setq tabulated-list-use-header-line Buffer-menu-use-header-line) (setq tabulated-list-entries (nreverse entries)) - (when Buffer-menu-group-by - (setq tabulated-list-groups - (seq-group-by Buffer-menu-group-by - tabulated-list-entries)))) + (setq tabulated-list-groups + (tabulated-list-groups + tabulated-list-entries + `(:path-function + ,(lambda (entry) + (list (mapcar (lambda (f) (funcall f entry)) + Buffer-menu-group-by))) + :sort-function + ,(lambda (groups) + ;; Sort groups by name + (sort groups :key #'car :in-place t)))))) (tabulated-list-init-header)) (defun tabulated-list-entry-size-> (entry1 entry2) @@ -799,16 +810,16 @@ See more at `Buffer-menu-filter-predicate'." (defun Buffer-menu-group-by-mode (entry) (let ((mode (aref (cadr entry) 5))) - (concat "* " (or (cdr (seq-find (lambda (group) - (string-match-p (car group) mode)) - mouse-buffer-menu-mode-groups)) - mode)))) + (or (cdr (seq-find (lambda (group) + (string-match-p (car group) mode)) + mouse-buffer-menu-mode-groups)) + mode))) (declare-function project-root "project" (project)) (defun Buffer-menu-group-by-root (entry) - (concat "* " (with-current-buffer (car entry) - (if-let ((project (project-current))) - (project-root project) - default-directory)))) + (with-current-buffer (car entry) + (if-let ((project (project-current))) + (project-root project) + default-directory))) ;;; buff-menu.el ends here diff --git a/lisp/emacs-lisp/tabulated-list.el b/lisp/emacs-lisp/tabulated-list.el index c86e3f9c5df..a0a58bf8b42 100644 --- a/lisp/emacs-lisp/tabulated-list.el +++ b/lisp/emacs-lisp/tabulated-list.el @@ -880,6 +880,84 @@ as the ewoc pretty-printer." (put 'tabulated-list-mode 'mode-class 'special) +;;; Tabulated list groups + +(defun tabulated-list-groups (entries metadata) + "Make a flat list of groups from list of ENTRIES. +Return the data structure suitable to be set to the variable +`tabulated-list-groups'. METADATA is a property list with two keys: +PATH-FUNCTION is a function to put an entry from ENTRIES to the tree +\(see `tabulated-list-groups-categorize' for more information); +SORT-FUNCTION is a function to sort groups in the tree +\(see `tabulated-list-groups-sort' for more information)." + (let* ((path-function (plist-get metadata :path-function)) + (sort-function (plist-get metadata :sort-function)) + (tree (tabulated-list-groups-categorize entries path-function))) + (when sort-function + (setq tree (tabulated-list-groups-sort tree sort-function))) + (tabulated-list-groups-flatten tree))) + +(defun tabulated-list-groups-categorize (entries path-function) + "Make a tree of groups from list of ENTRIES. +On each entry from ENTRIES apply PATH-FUNCTION that should return a list of +paths that the entry has on the group tree that means that every entry +can belong to multiple categories. Every path is a list of strings +where every string is an outline heading at increasing level of deepness." + (let ((tree nil) + (hash (make-hash-table :test #'equal))) + (cl-labels + ((trie-add (list tree) + (when list + (setf (alist-get (car list) tree nil nil #'equal) + (trie-add (cdr list) + (alist-get (car list) tree nil nil #'equal))) + tree)) + (trie-get (tree path) + (mapcar (lambda (elt) + (cons (car elt) + (if (cdr elt) + (trie-get (cdr elt) (cons (car elt) path)) + (apply #'vector (nreverse + (gethash (reverse + (cons (car elt) path)) + hash)))))) + (reverse tree)))) + (dolist (entry entries) + (dolist (path (funcall path-function entry)) + (unless (gethash path hash) + (setq tree (trie-add path tree))) + (cl-pushnew entry (gethash path hash)))) + (trie-get tree nil)))) + +(defun tabulated-list-groups-sort (tree sort-function) + "Sort TREE using the sort function SORT-FUN." + (mapcar (lambda (elt) + (if (vectorp (cdr elt)) + elt + (cons (car elt) (tabulated-list-groups-sort + (cdr elt) sort-function)))) + (funcall sort-function tree))) + +(defun tabulated-list-groups-flatten (tree) + "Flatten multi-level TREE to single level." + (let ((header "") acc) + (cl-labels + ((flatten (tree level) + (mapcar (lambda (elt) + (setq header (format "%s%s %s\n" header + (make-string level ?*) + (car elt))) + (cond + ((vectorp (cdr elt)) + (setq acc (cons (cons (string-trim-right header) + (append (cdr elt) nil)) + acc)) + (setq header "")) + (t (flatten (cdr elt) (1+ level))))) + tree))) + (flatten tree 1) + (nreverse acc)))) + (provide 'tabulated-list) ;;; tabulated-list.el ends here commit 6fbb699bee2f54d65fbe6074735d42bbc0868c2c Author: Eli Zaretskii Date: Wed Jun 5 19:32:17 2024 +0300 ; Fix last change. diff --git a/src/cm.c b/src/cm.c index f6101272d69..67fafa29bcc 100644 --- a/src/cm.c +++ b/src/cm.c @@ -22,6 +22,7 @@ along with GNU Emacs. If not, see . */ #include "lisp.h" #include "cm.h" +#include "frame.h" #include "sysstdio.h" #include "termchar.h" #include "tparam.h" commit e84057d072eaaa5e395d796a41bb78613844fb7c Author: Eli Zaretskii Date: Wed Jun 5 19:18:49 2024 +0300 Another attempt to prevent crashes when resizing TTY frames * src/dispnew.c (frame_size_change_delayed): Accept frame as argument, and check the 'new_size_p' flag of the frame in addition to 'delayed_size_change'. Callers changed. (window_to_frame_vpos, build_frame_matrix_from_leaf_window): Call 'frame_size_change_delayed' instead of looking at delayed_size_change alone. (Bug#71289) diff --git a/src/cm.c b/src/cm.c index c6c64d95a2a..f6101272d69 100644 --- a/src/cm.c +++ b/src/cm.c @@ -113,7 +113,7 @@ cmcheckmagic (struct tty_display_info *tty) { /* If we have an unhandled SIGWINCH, we don't really know what our up-to-date frame dimensions are. */ - if (frame_size_change_delayed ()) + if (frame_size_change_delayed (XFRAME (tty->top_frame))) return; if (curX (tty) == FrameCols (tty)) { diff --git a/src/dispextern.h b/src/dispextern.h index 8207e74a90c..35e1893c83c 100644 --- a/src/dispextern.h +++ b/src/dispextern.h @@ -3812,7 +3812,7 @@ extern void gui_update_window_end (struct window *, bool, bool); #endif void do_pending_window_change (bool); void change_frame_size (struct frame *, int, int, bool, bool, bool); -extern bool frame_size_change_delayed (void); +extern bool frame_size_change_delayed (struct frame *); void init_display (void); void syms_of_display (void); extern void spec_glyph_lookup_face (struct window *, GLYPH *); diff --git a/src/dispnew.c b/src/dispnew.c index dfa36a9f54f..a3c5cbbcf00 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -2643,7 +2643,7 @@ build_frame_matrix_from_leaf_window (struct glyph_matrix *frame_matrix, struct w #ifdef GLYPH_DEBUG /* Window row window_y must be a slice of frame row frame_y. */ - eassert (delayed_size_change + eassert (frame_size_change_delayed (XFRAME (w->frame)) || glyph_row_slice_p (window_row, frame_row)); /* If rows are in sync, we don't have to copy glyphs because @@ -3150,7 +3150,7 @@ window_to_frame_vpos (struct window *w, int vpos) eassert (!FRAME_WINDOW_P (XFRAME (w->frame))); eassert (vpos >= 0 && vpos <= w->desired_matrix->nrows); vpos += WINDOW_TOP_EDGE_LINE (w); - eassert (delayed_size_change + eassert (frame_size_change_delayed (XFRAME (w->frame)) || (vpos >= 0 && vpos <= FRAME_TOTAL_LINES (XFRAME (w->frame)))); return vpos; } @@ -6081,13 +6081,13 @@ change_frame_size (struct frame *f, int new_width, int new_height, change_frame_size_1 (f, new_width, new_height, pretend, delay, safe); } -/* Return non-zero if we delayed size-changes and haven't handled them - yet, which means we cannot be sure about the exact dimensions of our - frames. */ +/* Return non-zero if we delayed size-changes of frame F and haven't + handled them yet, which means we cannot be sure about the exact + dimensions of our frames. */ bool -frame_size_change_delayed (void) +frame_size_change_delayed (struct frame *f) { - return delayed_size_change; + return (delayed_size_change || f->new_size_p); } /*********************************************************************** commit cf9ff842395b8a4787b717d274c3151c1ab0a970 Author: Collin Funk Date: Wed Jun 5 04:13:32 2024 -0700 ; * .gitignore: Add lib/endian.h (bug#71378). Copyright-paperwork-exempt: yes diff --git a/.gitignore b/.gitignore index 52d328a9357..eb76ff330b8 100644 --- a/.gitignore +++ b/.gitignore @@ -78,6 +78,7 @@ lib/alloca.h lib/assert.h lib/byteswap.h lib/dirent.h +lib/endian.h lib/errno.h lib/execinfo.h lib/fcntl.h commit f240f482e2686f9c51d33b9e11b5884b12cef7aa Author: Eshel Yaron Date: Wed Jun 5 10:23:56 2024 +0200 New user option 'completion-preview-idle-delay' Support displaying the completion preview shortly after you pause typing (on idle) rather than immediately. * lisp/completion-preview.el (Commentary): Update. (completion-preview--try-update): (completion-preview--update-from-timer): New functions. (completion-preview--timer): New buffer-local variable. (completion-preview-idle-delay): New user option. (completion-preview--show): Use it. (completion-preview--post-command): (completion-preview-mode): Disable idle timer if active. diff --git a/lisp/completion-preview.el b/lisp/completion-preview.el index 730df45cb90..caebb9d01e3 100644 --- a/lisp/completion-preview.el +++ b/lisp/completion-preview.el @@ -59,6 +59,12 @@ ;; that should appear around point for Emacs to suggest a completion. ;; By default, this option is set to 3, so Emacs suggests a completion ;; if you type "foo", but typing just "fo" doesn't show the preview. +;; If you want the preview to appear also after non-symbol characters, +;; such as punctuation, set `completion-preview-minimum-symbol-length' +;; to nil. If you do so, you may want to customize the user option +;; `completion-preview-idle-delay' to have the preview appear only +;; when you pause typing for a short duration rather than after every +;; key. Try setting it to 0.2 seconds and see how that works for you. ;;; Code: @@ -114,6 +120,14 @@ If this option is nil, these commands do not display any message." (const :tag "No message" nil)) :version "30.1") +(defcustom completion-preview-idle-delay nil + "If non-nil, wait this many idle seconds before displaying completion preview. + +If this is nil, display the completion preview without delay." + :type '(choice (number :tag "Delay duration in seconds") + (const :tag "No delay" nil)) + :version "30.1") + (defvar completion-preview-sort-function #'minibuffer--sort-by-length-alpha "Sort function to use for choosing a completion candidate to preview.") @@ -350,6 +364,18 @@ candidates or if there are multiple matching completions and (overlay-put ov 'completion-preview-props props) (completion-preview-active-mode))))) +(defun completion-preview--try-update () + "Try to update completion preview, but give up as soon as input arrives." + (while-no-input (completion-preview--update))) + +(defun completion-preview--update-from-timer (window buffer) + "Update completion preview if WINDOW and BUFFER are current." + (when (and (eq (selected-window) window) (eq (current-buffer) buffer)) + (completion-preview--try-update))) + +(defvar-local completion-preview--timer nil + "Idle timer for updating the completion preview.") + (defun completion-preview--show () "Show a new completion preview. @@ -392,7 +418,12 @@ point, otherwise hide it." ;; The previous preview is no longer applicable, hide it. (completion-preview-active-mode -1)))) ;; Run `completion-at-point-functions' to get a new candidate. - (while-no-input (completion-preview--update))) + (if completion-preview-idle-delay + (setq completion-preview--timer + (run-with-idle-timer completion-preview-idle-delay + nil #'completion-preview--update-from-timer + (selected-window) (current-buffer))) + (completion-preview--try-update))) (defun completion-preview--post-command () "Create, update or delete completion preview post last command." @@ -401,6 +432,10 @@ point, otherwise hide it." completion-preview--internal-commands)))) (setq completion-preview--inhibit-update-p nil) + (when (timerp completion-preview--timer) + (cancel-timer completion-preview--timer) + (setq completion-preview--timer nil)) + ;; If we're called after a command that itself updates the ;; preview, don't do anything. (unless internal-p @@ -570,7 +605,10 @@ backward." (if completion-preview-mode (add-hook 'post-command-hook #'completion-preview--post-command nil t) (remove-hook 'post-command-hook #'completion-preview--post-command t) - (completion-preview-active-mode -1))) + (when completion-preview-active-mode (completion-preview-active-mode -1)) + (when (timerp completion-preview--timer) + (cancel-timer completion-preview--timer) + (setq completion-preview--timer nil)))) ;;;###autoload (define-globalized-minor-mode global-completion-preview-mode commit c11fe940064724e5c41af20fdb0f60c49952f936 Author: Eshel Yaron Date: Wed Jun 5 10:03:06 2024 +0200 Allow 'completion-preview-require-minimum-symbol-length' to be nil With some completion backends, completion preview is useful not only after a partial symbol, but also after punctuation and other non-symbol characters. For example, in C code it's helpful to display the completion preview for struct members when point is after 'foo->'. Provide an option to skip the check for minimum symbol length at point in order to support this use case. * lisp/completion-preview.el (completion-preview-minimum-symbol-length): Mention possible nil value in type and docstring. (completion-preview-require-minimum-symbol-length): Skip check if 'completion-preview-minimum-symbol-length' is nil. diff --git a/lisp/completion-preview.el b/lisp/completion-preview.el index 933ee24b620..730df45cb90 100644 --- a/lisp/completion-preview.el +++ b/lisp/completion-preview.el @@ -90,8 +90,12 @@ first candidate, and you can cycle between the candidates with :version "30.1") (defcustom completion-preview-minimum-symbol-length 3 - "Minimum length of the symbol at point for showing completion preview." - :type 'natnum + "Minimum length of the symbol at point for showing completion preview. + +If this is nil rather than a number of characters, show the preview also +after non-symbol characters, such as punctuation or whitespace." + :type '(choice (natnum :tag "Minimum number of symbol characters") + (const :tag "Disable minimum symbol length requirement" nil)) :version "30.1") (defcustom completion-preview-message-format @@ -195,9 +199,10 @@ Completion Preview mode avoids updating the preview after these commands.") (defun completion-preview-require-minimum-symbol-length () "Check if the length of symbol at point is at least above a certain threshold. `completion-preview-minimum-symbol-length' determines that threshold." - (let ((bounds (bounds-of-thing-at-point 'symbol))) - (and bounds (<= completion-preview-minimum-symbol-length - (- (cdr bounds) (car bounds)))))) + (or (null completion-preview-minimum-symbol-length) + (let ((bounds (bounds-of-thing-at-point 'symbol))) + (and bounds (<= completion-preview-minimum-symbol-length + (- (cdr bounds) (car bounds))))))) (defun completion-preview-hide () "Hide the completion preview." commit b2ed1ed1d87c9a3c306554ab7a653717450cc562 Author: Po Lu Date: Wed Jun 5 17:11:27 2024 +0800 Fix Mac OS build * src/nsfns.m (ns_make_frame_key_window): Restore, but only when NS_IMPL_COCOA. diff --git a/src/nsfns.m b/src/nsfns.m index 23f23375976..24fabbe2eaa 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -690,6 +690,16 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side. SET_FRAME_GARBAGED (f); } +#ifdef NS_IMPL_COCOA + +void +ns_make_frame_key_window (struct frame *f) +{ + [[FRAME_NS_VIEW (f) window] makeKeyWindow]; +} + +#endif /* NS_IMPL_COCOA */ + /* tabbar support */ static void ns_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) commit 533ed7b221ab40be217e951e925739360e457b50 Author: Po Lu Date: Wed Jun 5 16:41:52 2024 +0800 Fix the GNUstep build * src/Makefile.in (NON_OBJC_CFLAGS): Add -Wflex-array-member-not-at-end. * src/lisp.h (flush_stack_call_func): "asm" is unavailable in Objective C. * src/nsfns.m (ns_make_frame_key_window): Delete unused function. diff --git a/src/Makefile.in b/src/Makefile.in index a14ae5eacb8..cac0b4ea280 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -423,7 +423,7 @@ endif # Flags that might be in WARN_CFLAGS but are not valid for Objective C. NON_OBJC_CFLAGS = -Wignored-attributes -Wignored-qualifiers -Wopenmp-simd \ - -Wnested-externs -Wstrict-flex-arrays + -Wnested-externs -Wstrict-flex-arrays -Wflex-array-member-not-at-end # Ditto, but for C++. NON_CXX_CFLAGS = -Wmissing-prototypes -Wnested-externs -Wold-style-definition \ -Wstrict-prototypes -Wno-override-init diff --git a/src/lisp.h b/src/lisp.h index 67fcb146515..e1911cbb660 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4508,7 +4508,7 @@ flush_stack_call_func (void (*func) (void *arg), void *arg) /* Work around GCC sibling call optimization making '__builtin_unwind_init' ineffective (bug#65727). See . */ -#if defined __GNUC__ && !defined __clang__ +#if defined __GNUC__ && !defined __clang__ && !defined __OBJC__ asm (""); #endif } diff --git a/src/nsfns.m b/src/nsfns.m index b08d053610f..23f23375976 100644 --- a/src/nsfns.m +++ b/src/nsfns.m @@ -690,12 +690,6 @@ Turn the input menu (an NSMenu) into a lisp list for tracking on lisp side. SET_FRAME_GARBAGED (f); } -void -ns_make_frame_key_window (struct frame *f) -{ - [[FRAME_NS_VIEW (f) window] makeKeyWindow]; -} - /* tabbar support */ static void ns_set_tab_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval)