commit ea12982ebedd89529c0265dec117db88e7e9ca40 (HEAD, refs/remotes/origin/master) Author: Stefan Kangas Date: Wed Feb 26 07:21:51 2025 +0100 Revert "Correctly fill generated ChangeLog entries" This reverts commit 7fe90ca77d0c21165cb9d98d5c42d6b6c6275ef3. diff --git a/lisp/vc/add-log.el b/lisp/vc/add-log.el index 7f0dbfbc46e..31418540b59 100644 --- a/lisp/vc/add-log.el +++ b/lisp/vc/add-log.el @@ -326,9 +326,7 @@ CHANGELOGS is a list in the form returned by (insert ":\n") (insert " ") (cl-loop for def in defuns - do (progn - (insert "(" def "):\n") - (log-edit-fill-entry)))))) + do (insert "(" def "):\n"))))) (defun change-log-find-file () "Visit the file for the change under point." commit b4d1061b82a6accedc14770669f701945b209813 Author: Stefan Kangas Date: Wed Feb 26 06:37:52 2025 +0100 Make define-global-minor-mode alias obsolete * lisp/emacs-lisp/easy-mmode.el (define-global-minor-mode): Make alias for old name obsolete, just in time for its 20th anniversary. * test/lisp/emacs-lisp/lisp-mode-tests.el (test-font-lock-keywords): * lisp/progmodes/subword.el (global-subword-mode) (global-superword-mode): Don't use above obsolete name. * lisp/emacs-lisp/lisp-mode.el (lisp-imenu-generic-expression) (lisp-fdefs): Remove syntax highlighting for obsolete name. * lisp/emacs-lisp/loaddefs-gen.el (loaddefs-generate--make-autoload): Add comment mentioning the obsolete status of above alias. * doc/lispref/loading.texi (Autoload): Don't document obsolete name. diff --git a/doc/lispref/loading.texi b/doc/lispref/loading.texi index 750f6e76eff..15922cf1e89 100644 --- a/doc/lispref/loading.texi +++ b/doc/lispref/loading.texi @@ -659,8 +659,8 @@ and @code{define-overloadable-function} (see the commentary in @item Definitions for major or minor modes: @code{define-minor-mode}, @code{define-globalized-minor-mode}, -@code{define-generic-mode}, @code{define-derived-mode}, -@code{define-compilation-mode}, and @code{define-global-minor-mode}. +@code{define-generic-mode}, @code{define-derived-mode}, and +@code{define-compilation-mode}. @item Other definition types: @code{defcustom}, @code{defgroup}, @code{deftheme}, @code{defclass} diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el index 2f63fc90f53..e59799df383 100644 --- a/lisp/emacs-lisp/easy-mmode.el +++ b/lisp/emacs-lisp/easy-mmode.el @@ -443,8 +443,6 @@ No problems result if this variable is not bound. ;;; make global minor mode ;;; -;;;###autoload -(defalias 'define-global-minor-mode #'define-globalized-minor-mode) ;;;###autoload (defmacro define-globalized-minor-mode (global-mode mode turn-on &rest body) "Make a global mode GLOBAL-MODE corresponding to buffer-local minor MODE. @@ -852,11 +850,14 @@ Interactively, COUNT is the prefix numeric argument, and defaults to 1." name) ,@body) (put ',prev-sym 'definition-name ',base)))) -;; When deleting these two, also delete them from loaddefs-gen.el. +;; When deleting these, also delete them from loaddefs-gen.el. ;;;###autoload (define-obsolete-function-alias 'easy-mmode-define-minor-mode #'define-minor-mode "30.1") ;;;###autoload (define-obsolete-function-alias 'easy-mmode-define-global-mode #'define-globalized-minor-mode "30.1") +;;;###autoload +(define-obsolete-function-alias 'define-global-minor-mode + #'define-globalized-minor-mode "31.1") (provide 'easy-mmode) diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index 9bed4374dff..30cbfaf24f3 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -101,7 +101,6 @@ "defun*" "defsubst" "define-inline" "define-advice" "defadvice" "define-skeleton" "define-compilation-mode" "define-minor-mode" - "define-global-minor-mode" "define-globalized-minor-mode" "define-derived-mode" "define-generic-mode" "ert-deftest" @@ -352,7 +351,7 @@ This will generate compile-time constants from BINDINGS." (el-fdefs '("defsubst" "cl-defsubst" "define-inline" "define-advice" "defadvice" "defalias" "define-derived-mode" "define-minor-mode" - "define-generic-mode" "define-global-minor-mode" + "define-generic-mode" "define-globalized-minor-mode" "define-skeleton" "define-widget" "ert-deftest")) (el-vdefs '("defconst" "defcustom" "defvaralias" "defvar-local" diff --git a/lisp/emacs-lisp/loaddefs-gen.el b/lisp/emacs-lisp/loaddefs-gen.el index 2387a5d4b92..2a2f3747ac9 100644 --- a/lisp/emacs-lisp/loaddefs-gen.el +++ b/lisp/emacs-lisp/loaddefs-gen.el @@ -197,11 +197,14 @@ expression, in which case we want to handle forms differently." (when exps (cons 'progn exps))))) ;; For complex cases, try again on the macro-expansion. - ((and (memq car '(easy-mmode-define-global-mode define-global-minor-mode - define-globalized-minor-mode defun defmacro - easy-mmode-define-minor-mode define-minor-mode - define-inline cl-defun cl-defmacro cl-defgeneric - cl-defstruct pcase-defmacro iter-defun cl-iter-defun)) + ((and (memq car '( define-globalized-minor-mode defun defmacro + define-minor-mode define-inline + cl-defun cl-defmacro cl-defgeneric + cl-defstruct pcase-defmacro iter-defun cl-iter-defun + ;; Obsolete; keep until the alias is removed. + easy-mmode-define-global-mode + easy-mmode-define-minor-mode + define-global-minor-mode)) (macrop car) (setq expand (let ((load-true-file-name file) (load-file-name file)) @@ -211,15 +214,18 @@ expression, in which case we want to handle forms differently." (loaddefs-generate--make-autoload expand file 'expansion)) ;; For special function-like operators, use the `autoload' function. - ((memq car '(define-skeleton define-derived-mode + ((memq car '( define-skeleton define-derived-mode define-compilation-mode define-generic-mode - easy-mmode-define-global-mode define-global-minor-mode - define-globalized-minor-mode - easy-mmode-define-minor-mode define-minor-mode + define-globalized-minor-mode + define-minor-mode cl-defun defun* cl-defmacro defmacro* define-overloadable-function transient-define-prefix transient-define-suffix - transient-define-infix transient-define-argument)) + transient-define-infix transient-define-argument + ;; Obsolete; keep until the alias is removed. + easy-mmode-define-global-mode + easy-mmode-define-minor-mode + define-global-minor-mode)) (let* ((macrop (memq car '(defmacro cl-defmacro defmacro*))) (name (nth 1 form)) (args (pcase car @@ -243,17 +249,18 @@ expression, in which case we want to handle forms differently." (loaddefs-generate--shorten-autoload `(autoload ,(if (listp name) name (list 'quote name)) ,file ,doc - ,(or (and (memq car '(define-skeleton define-derived-mode + ,(or (and (memq car '( define-skeleton define-derived-mode define-generic-mode - easy-mmode-define-global-mode - define-global-minor-mode define-globalized-minor-mode - easy-mmode-define-minor-mode define-minor-mode transient-define-prefix transient-define-suffix transient-define-infix - transient-define-argument)) + transient-define-argument + ;; Obsolete; keep until the alias is removed. + easy-mmode-define-global-mode + easy-mmode-define-minor-mode + define-global-minor-mode)) t) (and (eq (car-safe (car body)) 'interactive) ;; List of modes or just t. diff --git a/lisp/progmodes/subword.el b/lisp/progmodes/subword.el index 3db64d5319f..4305e36c33f 100644 --- a/lisp/progmodes/subword.el +++ b/lisp/progmodes/subword.el @@ -119,7 +119,7 @@ treat nomenclature boundaries as word boundaries." (define-obsolete-function-alias 'c-subword-mode 'subword-mode "23.2") ;;;###autoload -(define-global-minor-mode global-subword-mode subword-mode +(define-globalized-minor-mode global-subword-mode subword-mode (lambda () (subword-mode 1)) :group 'convenience) @@ -273,7 +273,7 @@ syntax are treated as parts of words: e.g., in `superword-mode', (subword-setup-buffer)) ;;;###autoload -(define-global-minor-mode global-superword-mode superword-mode +(define-globalized-minor-mode global-superword-mode superword-mode (lambda () (superword-mode 1)) :group 'convenience) diff --git a/test/lisp/emacs-lisp/lisp-mode-tests.el b/test/lisp/emacs-lisp/lisp-mode-tests.el index 083030c73a6..f8f9330d4c7 100644 --- a/test/lisp/emacs-lisp/lisp-mode-tests.el +++ b/test/lisp/emacs-lisp/lisp-mode-tests.el @@ -420,7 +420,7 @@ lisp-fill-paragraph was refactored in version 28.\")")) '("defsubst" "cl-defsubst" "define-inline" "define-advice" "defadvice" "defalias" "define-derived-mode" "define-minor-mode" - "define-generic-mode" "define-global-minor-mode" + "define-generic-mode" "define-globalized-minor-mode" "define-skeleton" "define-widget" "ert-deftest" "defconst" "defcustom" "defvaralias" "defvar-local" "defface" "define-error")))) commit 8bc933b64e0582def4c19b4cc633eaabdff625ce Author: john muhl Date: Mon Feb 24 15:21:38 2025 -0600 ; Cleanup sexp things in 'lua-ts-mode' * lisp/progmodes/lua-ts-mode.el (lua-ts-mode): Remove some nonsensical entries from 'treesit-thing-settings'. * test/lisp/progmodes/lua-ts-mode-resources/movement.erts: Add missing tests for 'backward-sexp'. (Bug#76534) diff --git a/lisp/progmodes/lua-ts-mode.el b/lisp/progmodes/lua-ts-mode.el index f02fefa8f94..de93d0fdaba 100644 --- a/lisp/progmodes/lua-ts-mode.el +++ b/lisp/progmodes/lua-ts-mode.el @@ -793,8 +793,7 @@ Calls REPORT-FN directly." `((lua (function ,(rx (or "function_declaration" "function_definition"))) - (keyword ,(regexp-opt lua-ts--keywords - 'symbols)) + (keyword ,(regexp-opt lua-ts--keywords 'symbols)) (loop-statement ,(rx (or "do_statement" "for_statement" "repeat_statement" @@ -812,18 +811,10 @@ Calls REPORT-FN directly." keyword loop-statement ,(rx (or "arguments" - "break_statement" - "expression_list" - "false" - "identifier" - "nil" - "number" "parameters" "parenthesized_expression" "string" - "table_constructor" - "true" - "vararg_expression")))) + "table_constructor")))) (text "comment")))) ;; Imenu/Outline/Which-function. diff --git a/test/lisp/progmodes/lua-ts-mode-resources/movement.erts b/test/lisp/progmodes/lua-ts-mode-resources/movement.erts index 11e86f12926..6e2ffb21d0e 100644 --- a/test/lisp/progmodes/lua-ts-mode-resources/movement.erts +++ b/test/lisp/progmodes/lua-ts-mode-resources/movement.erts @@ -436,9 +436,9 @@ function f(a, b)| end Name: forward-sexp moves over strings =-= -print("|1, 2, 3") +print(|"1, 2, 3") =-= -print("1, 2, 3|") +print("1, 2, 3"|) =-=-= Name: forward-sexp moves over tables @@ -557,9 +557,9 @@ function f|(a, b) end Name: backward-sexp moves over strings =-= -print("1, 2, 3|") +print("1, 2, 3"|) =-= -print("|1, 2, 3") +print(|"1, 2, 3") =-=-= Name: backward-sexp moves over tables @@ -601,3 +601,53 @@ end| end end =-=-= + +Name: backward-sexp moves over do statements + +=-= +do + print(a + 1) +end| +=-= +|do + print(a + 1) +end +=-=-= + +Name: backward-sexp moves over for statements + +=-= +for k,v in pairs({}) do + print(k, v) +end| +=-= +|for k,v in pairs({}) do + print(k, v) +end +=-=-= + +Name: backward-sexp moves over repeat statements + +=-= +repeat + n = n + 1 +until n > 10| +=-= +|repeat + n = n + 1 +until n > 10 +=-=-= + +Name: backward-sexp moves over while statements + +=-= +while n < 99 +do + n = n+1 +end| +=-= +|while n < 99 +do + n = n+1 +end +=-=-= commit 539772135222755255a3c8ca0cdda73dc4d742b2 Author: Stefan Kangas Date: Wed Feb 26 04:36:51 2025 +0100 Don't enable minor modes in diff-add-log-current-defuns * lisp/vc/diff-mode.el (diff-add-log-current-defuns): Don't run mode hooks when enabling major mode hooks. That fails if, for example, paredit-mode is on emacs-lisp-mode-hook and it signaled due to unbalanced parens. diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index 40ec6121c3e..16e696b6609 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -2663,7 +2663,8 @@ are relative to the root directory of the VC repository." (if other-buf (set-buffer other-buf) (set-buffer (generate-new-buffer " *diff-other-text*")) (insert (if applied old-text new-text)) - (funcall (buffer-local-value 'major-mode buf)) + (let ((delay-mode-hooks t)) + (funcall (buffer-local-value 'major-mode buf))) (setq other-buf (current-buffer))) (goto-char (point-min)) (forward-line (+ =lines -1 commit 2938afab3685f29c80d67f179ce8a935f6c27921 Author: Po Lu Date: Wed Feb 26 11:33:05 2025 +0800 Adapt a number of regression tests to Android * test/infra/android/test-controller.el (ats-run-test): Strip text properties from value string. Inhibit text conversion. * test/lisp/emacs-lisp/find-func-tests.el (find-func-tests--locate-symbols): * test/lisp/emacs-lisp/rmc-tests.el (test-rmc--add-key-description) (test-rmc--add-key-description/with-attributes) (test-rmc--add-key-description/non-graphical-display) (test-read-multiple-choice, test-read-multiple-choice-help): Skip on Android in some wise or another. diff --git a/test/infra/android/test-controller.el b/test/infra/android/test-controller.el index be4fc4586d7..89b9b93f7b1 100644 --- a/test/infra/android/test-controller.el +++ b/test/infra/android/test-controller.el @@ -2436,6 +2436,7 @@ Display the output of the tests executed in a buffer." ;; present... (ert-remote-temporary-file-directory null-device) + (overriding-text-conversion-style nil) (set-message-function (lambda (message) (with-current-buffer temp-buffer @@ -2443,7 +2444,8 @@ Display the output of the tests executed in a buffer." (let ((noninteractive t)) (ert-run-tests-batch ',selector)) (insert "=== Test execution complete ===\n") - (buffer-string)))))) + (buffer-substring-no-properties + (point-min) (point-max))))))) (cond ((eq (car rc) 'error) (error "Error executing `%s-tests.el': %S" test (cdr rc))) (t (progn diff --git a/test/lisp/emacs-lisp/find-func-tests.el b/test/lisp/emacs-lisp/find-func-tests.el index 077f1cbffd2..3faf9f99aff 100644 --- a/test/lisp/emacs-lisp/find-func-tests.el +++ b/test/lisp/emacs-lisp/find-func-tests.el @@ -45,6 +45,8 @@ (read-library-name))))) (ert-deftest find-func-tests--locate-symbols () + ;; C source files are unavailable when testing on Android. + (skip-when (featurep 'android)) (should (cdr (find-function-search-for-symbol #'goto-line nil "simple"))) diff --git a/test/lisp/emacs-lisp/rmc-tests.el b/test/lisp/emacs-lisp/rmc-tests.el index 0237bc3f9e5..c1ee14771da 100644 --- a/test/lisp/emacs-lisp/rmc-tests.el +++ b/test/lisp/emacs-lisp/rmc-tests.el @@ -30,6 +30,7 @@ (eval-when-compile (require 'cl-lib)) (ert-deftest test-rmc--add-key-description () + (skip-when (display-graphic-p)) (cl-letf (((symbol-function 'display-supports-face-attributes-p) (lambda (_ _) t))) (should (equal (rmc--add-key-description '(?y "yes")) '(?y . "yes"))) @@ -39,6 +40,7 @@ `(?\s . "SPC foo bar"))))) (ert-deftest test-rmc--add-key-description/with-attributes () + (skip-when (display-graphic-p)) (cl-letf (((symbol-function 'display-supports-face-attributes-p) (lambda (_ _) t))) (should (equal-including-properties (rmc--add-key-description '(?y "yes")) @@ -51,6 +53,7 @@ `(?\s . ,(concat (propertize "SPC" 'face 'read-multiple-choice-face) " foo bar")))))) (ert-deftest test-rmc--add-key-description/non-graphical-display () + (skip-when (display-graphic-p)) (cl-letf (((symbol-function 'display-supports-face-attributes-p) (lambda (_ _) nil))) (should (equal-including-properties (rmc--add-key-description '(?y "yes")) @@ -60,6 +63,7 @@ `(?n . ,(concat (propertize "n" 'face 'help-key-binding) " foo")))))) (ert-deftest test-read-multiple-choice () + (skip-when (display-graphic-p)) (dolist (char '(?y ?n)) (cl-letf* (((symbol-function #'read-key) (lambda () char)) (str (if (eq char ?y) "yes" "no"))) @@ -67,6 +71,7 @@ (read-multiple-choice "Do it? " '((?y "yes") (?n "no")))))))) (ert-deftest test-read-multiple-choice-help () + (skip-when (display-graphic-p)) (let ((chars '(?o ?a)) help) (cl-letf* (((symbol-function #'read-key) commit ecde11a83cfcfbb7c5ff1a7244464f53a7c68687 Author: Stefan Kangas Date: Wed Feb 26 03:47:02 2025 +0100 ; Silence byte-compiler diff --git a/lisp/vc/add-log.el b/lisp/vc/add-log.el index a5131ee3a33..7f0dbfbc46e 100644 --- a/lisp/vc/add-log.el +++ b/lisp/vc/add-log.el @@ -314,10 +314,12 @@ as a list of strings." ",[[:blank:]]*" t) finally do (skip-chars-backward "\n[:blank:]"))) +(declare-function log-edit-fill-entry "log-edit") (defun change-log-insert-entries (changelogs) "Format and insert CHANGELOGS into current buffer. CHANGELOGS is a list in the form returned by `diff-add-log-current-defuns'." + (require 'log-edit) (cl-loop for (file . defuns) in changelogs do (insert "* " file) (if (not defuns) commit c2804f928097ddea4826b232e310417320bb5ce0 Author: Po Lu Date: Wed Feb 26 10:35:00 2025 +0800 ; Improve Android testing facilities * test/infra/android/test-controller.el (ats-eval): Don't block other processes. (ats-run-test): Bind ert-remote-temporary-file-directory to nil and always print messages into the output buffer. (ats-upload-all-tests): New function. (ats-run-all-tests): New argument SELECTOR. Only execute already uploaded tests. diff --git a/test/infra/android/test-controller.el b/test/infra/android/test-controller.el index 0df7725e574..be4fc4586d7 100644 --- a/test/infra/android/test-controller.el +++ b/test/infra/android/test-controller.el @@ -1934,7 +1934,7 @@ manner." ;; (prog1 (accept-process-output process nil nil 1) ;; (setq ats-eval-tm (+ (- (float-time) t1) ;; ats-eval-tm)))) - (when (accept-process-output process nil nil 1) + (when (accept-process-output process) (when (not size) ;; First skip all output till the header is read. (save-excursion @@ -2430,10 +2430,16 @@ Display the output of the tests executed in a buffer." (ert-delete-all-tests) (load ,file-name) (with-temp-buffer - (let ((standard-output (current-buffer)) - (set-message-function - (lambda (message) - (insert message "\n")))) + (let* ((temp-buffer (current-buffer)) + (standard-output temp-buffer) + ;; Disable remote tests for the + ;; present... + (ert-remote-temporary-file-directory + null-device) + (set-message-function + (lambda (message) + (with-current-buffer temp-buffer + (insert message "\n"))))) (let ((noninteractive t)) (ert-run-tests-batch ',selector)) (insert "=== Test execution complete ===\n") @@ -2445,11 +2451,9 @@ Display the output of the tests executed in a buffer." (insert (cdr rc)) (pop-to-buffer (current-buffer)))))))) -(defun ats-run-all-tests (process dir) - "Run all Emacs tests defined in DIR on the device represented by PROCESS. -Upload each and every test defined in DIR to the said device, -and execute them in sequence. With a prefix argument, just run -the tests without uploading them." +(defun ats-upload-all-tests (process dir) + "Upload every Emacs test in DIR to the device represented by PROCESS. +Upload each and every test defined in DIR to the said device." (interactive (list (ats-read-connection "Connection: ") (or ats-emacs-test-directory @@ -2459,10 +2463,18 @@ the tests without uploading them." (unless current-prefix-arg (dolist-with-progress-reporter (test tests) "Uploading tests to device..." - (ats-upload-test process dir test))) + (ats-upload-test process dir test))))) + +(defun ats-run-all-tests (process &optional selector) + "Run every Emacs test uploaded to the device represented by PROCESS. +Execute every Emacs test that has been uploaded to PROCESS, +subject to SELECTOR, as in `ert-run-tests'." + (interactive (list (ats-read-connection "Connection: ") + (and current-prefix-arg (read)))) + (let ((tests (ats-list-tests process))) (dolist-with-progress-reporter (test tests) "Running tests..." - (ats-run-test process test)))) + (ats-run-test process test selector)))) (provide 'test-controller) commit c5853892c58be8e1c543177967850dceb1f4bcbc Author: Po Lu Date: Wed Feb 26 10:33:30 2025 +0800 Enable auto-revert-tests to pass on Android * lisp/emacs-lisp/ert-x.el (ert-remote-temporary-file-directory): Define to null-device on Android. * test/lisp/autorevert-tests.el (auto-revert-test02-auto-revert-deleted-file): Provide for situations where the watch descriptor is recreated by the polling timer after a file notification is received. diff --git a/lisp/emacs-lisp/ert-x.el b/lisp/emacs-lisp/ert-x.el index 38f98029891..ec2106dda22 100644 --- a/lisp/emacs-lisp/ert-x.el +++ b/lisp/emacs-lisp/ert-x.el @@ -392,6 +392,9 @@ The same keyword arguments are supported as in (cond ((getenv "REMOTE_TEMPORARY_FILE_DIRECTORY")) ((eq system-type 'windows-nt) null-device) + ;; Android's built-in shell is far too dysfunctional to support + ;; Tramp. + ((eq system-type 'android) null-device) (t (add-to-list 'tramp-methods '("mock" diff --git a/test/lisp/autorevert-tests.el b/test/lisp/autorevert-tests.el index d8115b444de..4aab58a6f02 100644 --- a/test/lisp/autorevert-tests.el +++ b/test/lisp/autorevert-tests.el @@ -295,6 +295,7 @@ This expects `auto-revert--messages' to be bound by (ert-with-message-capture auto-revert--messages (auto-revert-tests--write-file "another text" tmpfile (pop times)) + (should (eq desc auto-revert-notify-watch-descriptor)) (auto-revert--wait-for-revert buf)) ;; Check, that the buffer hasn't been reverted. File ;; notification should be disabled, falling back to @@ -304,7 +305,14 @@ This expects `auto-revert--messages' to be bound by (or (eq file-notify--library 'w32notify) (getenv "EMACS_EMBA_CI") (should-not - (file-notify-valid-p auto-revert-notify-watch-descriptor))) + ;; The auto-revert timer is wont to establish a new + ;; watch soon after the previous descriptor is + ;; destroyed, which not unnaturally interferes with + ;; our testing for its destruction, since descriptor + ;; IDs are reused. Therefore, test the identity of + ;; the previous descriptor, not just its validity. + (and (eq desc auto-revert-notify-watch-descriptor) + (file-notify-valid-p auto-revert-notify-watch-descriptor)))) ;; Once the file has been recreated, the buffer shall be ;; reverted. commit 928dc34e05fc04a9b8394df477beca2ef6d9fd1b Author: Po Lu Date: Wed Feb 26 09:56:46 2025 +0800 Guarantee delivery of inotify special events * src/inotify.c (inotifyevent_to_event): Always match events that are not encompassed by IN_ALL_EVENTS and which the documentation implies are always delivered to callbacks. * test/src/inotify-tests.el (inotify-file-watch-stop-delivery): New test. diff --git a/src/inotify.c b/src/inotify.c index ff842ddc58c..c29d940c984 100644 --- a/src/inotify.c +++ b/src/inotify.c @@ -187,7 +187,10 @@ inotifyevent_to_event (Lisp_Object watch, struct inotify_event const *ev) uint32_t mask; CONS_TO_INTEGER (Fnth (make_fixnum (3), watch), uint32_t, mask); - if (! (mask & ev->mask)) + if (! (mask & ev->mask) + /* These event types are supposed to be reported whether or not + they appeared in the ASPECT list when monitoring commenced. */ + && !(ev->mask & (IN_IGNORED | IN_Q_OVERFLOW | IN_ISDIR | IN_UNMOUNT))) return Qnil; if (ev->len > 0) diff --git a/test/src/inotify-tests.el b/test/src/inotify-tests.el index 23febef2c67..aa7801d1e2c 100644 --- a/test/src/inotify-tests.el +++ b/test/src/inotify-tests.el @@ -67,6 +67,17 @@ (inotify-rm-watch wd) (should-not (inotify-valid-p wd))))))) +(ert-deftest inotify-file-watch-stop-delivery () + "Test whether IN_IGNORE events are delivered." + (skip-unless (featurep 'inotify)) + (progn + (ert-with-temp-file temp-file + (inotify-add-watch + temp-file t (lambda (event) + (when (memq 'ignored (cadr event)) + (throw 'success t))))) + (should (catch 'success (recursive-edit) nil)))) + (provide 'inotify-tests) ;;; inotify-tests.el ends here commit 68f9a7aac1f5b9606ca6245e1dd74d09087752d4 Author: Stefan Kangas Date: Wed Feb 26 03:15:37 2025 +0100 ; Prefer incf/decf in image-dired * lisp/image/image-dired-dired.el (image-dired-mark-tagged-files): * lisp/image/image-dired.el (image-dired-gallery-generate): Prefer incf/decf. diff --git a/lisp/image/image-dired-dired.el b/lisp/image/image-dired-dired.el index c7994cd4096..a7d5ad7c3ec 100644 --- a/lisp/image/image-dired-dired.el +++ b/lisp/image/image-dired-dired.el @@ -384,7 +384,7 @@ matching tag will be marked in the Dired buffer." (setq curr-file (file-name-nondirectory curr-file)) (goto-char (point-min)) (when (search-forward-regexp (format "\\s %s[*@]?$" (regexp-quote curr-file)) nil t) - (setq hits (+ hits 1)) + (incf hits) (dired-mark 1)))) (message "%d files with matching tag marked" hits))) diff --git a/lisp/image/image-dired.el b/lisp/image/image-dired.el index 5bcf238e699..c344949ef31 100644 --- a/lisp/image/image-dired.el +++ b/lisp/image/image-dired.el @@ -1990,7 +1990,7 @@ when using per-directory thumbnail file storage")) (setq tag-link-list (append tag-link-list (list (cons tag tag-link)))) (setq tag-link-list (list (cons tag tag-link)))) - (setq count (1+ count)))) + (incf count))) (setq count 1) ;; Main loop where we generated thumbnail pages per tag (dolist (curr tags) @@ -2037,7 +2037,7 @@ when using per-directory thumbnail file storage")) (insert "

Index

\n") (insert " \n") (insert "\n")) - (setq count (1+ count)))) + (incf count))) (insert " \n") (insert "")))) @@ -2099,7 +2099,7 @@ when using per-directory thumbnail file storage")) ;; (format "Size of thumbnail directory: %d, delete old file %s? " ;; dirsize (cadr (cdar files)))) ;; (delete-file (cadr (cdar files))) -;; (setq dirsize (- dirsize (car (cdar files)))) +;; (decf dirsize (car (cdar files))) ;; (setq files (cdr files))))) (provide 'image-dired) commit 7fe90ca77d0c21165cb9d98d5c42d6b6c6275ef3 Author: Stefan Kangas Date: Wed Feb 26 03:13:38 2025 +0100 Correctly fill generated ChangeLog entries This fixes both 'C-c C-v' in VC and 'magit-generate-changelog'. * lisp/vc/add-log.el (change-log-insert-entries): Correctly fill generated ChangeLog entries. diff --git a/lisp/vc/add-log.el b/lisp/vc/add-log.el index 2208f50812e..a5131ee3a33 100644 --- a/lisp/vc/add-log.el +++ b/lisp/vc/add-log.el @@ -324,7 +324,9 @@ CHANGELOGS is a list in the form returned by (insert ":\n") (insert " ") (cl-loop for def in defuns - do (insert "(" def "):\n"))))) + do (progn + (insert "(" def "):\n") + (log-edit-fill-entry)))))) (defun change-log-find-file () "Visit the file for the change under point." commit dfcfb9792cfa9dacb890ab7e5b63e3adbe1cc6c0 Author: Stefan Kangas Date: Wed Feb 26 03:01:15 2025 +0100 ; Add missing require to wdired.el diff --git a/lisp/wdired.el b/lisp/wdired.el index 03cbf7131cf..c3773b358cc 100644 --- a/lisp/wdired.el +++ b/lisp/wdired.el @@ -69,6 +69,7 @@ ;;; Code: (require 'dired) +(eval-when-compile (require 'cl-lib)) (autoload 'dired-do-create-files-regexp "dired-aux") (defgroup wdired nil commit fa0131723c3d59240c3bf9b6cd6c0d8abc4ef63f Author: Stefan Kangas Date: Sun Feb 23 02:55:14 2025 +0100 Prefer incf to cl-incf in remaining files * admin/syncdoc-type-hierarchy.el (syncdoc-make-type-table): * admin/unidata/unidata-gen.el (unidata-gen-table-word-list): * lisp/arc-mode.el (archive--summarize-descs): * lisp/auth-source.el (auth-source-forget+): * lisp/battery.el (battery-linux-proc-acpi, battery-linux-sysfs): * lisp/calendar/parse-time.el (parse-time-tokenize): * lisp/calendar/time-date.el (decoded-time-add) (decoded-time--alter-month, decoded-time--alter-day): * lisp/cedet/semantic/ede-grammar.el (project-compile-target): * lisp/dired.el (dired-insert-set-properties): * lisp/edmacro.el (edmacro-format-keys): * lisp/epa-file.el (epa-file--replace-text): * lisp/eshell/esh-cmd.el (eshell-for-iterate): * lisp/eshell/esh-io.el (eshell-create-handles) (eshell-duplicate-handles, eshell-protect-handles) (eshell-copy-output-handle, eshell-buffered-print): * lisp/font-lock.el (font-lock-fontify-keywords-region): * lisp/help-fns.el: * lisp/ibuf-ext.el (ibuffer-generate-filter-groups) (ibuffer-insert-filter-group-before): * lisp/ibuffer.el (ibuffer-confirm-operation-on, ibuffer-map-lines): * lisp/image/image-dired-external.el (image-dired-thumb-queue-run): * lisp/image/image-dired.el (image-dired-display-thumbs) (image-dired-line-up): * lisp/imenu.el (imenu--split): * lisp/info-xref.el (info-xref-check-node, info-xref-check-all-custom): * lisp/international/quail.el (quail-insert-decode-map): * lisp/international/rfc1843.el (rfc1843-decode): * lisp/mail/ietf-drums-date.el (ietf-drums-date--tokenize-string): * lisp/mail/ietf-drums.el (ietf-drums-token-to-list): * lisp/mail/rfc2047.el (rfc2047-qp-or-base64): * lisp/mail/rfc2231.el (rfc2231-encode-string): * lisp/mail/yenc.el (yenc-decode-region): * lisp/mh-e/mh-e.el (mh-xargs): * lisp/mh-e/mh-folder.el (mh-recenter): * lisp/mh-e/mh-mime.el (mh-mime-part-index): * lisp/mh-e/mh-search.el (mh-search): * lisp/mh-e/mh-thread.el (mh-thread-current-indentation-level): * lisp/mh-e/mh-utils.el (mh-sub-folders-parse): * lisp/minibuffer.el (minibuffer--sort-by-position) (completion-pcm--pattern-point-idx): * lisp/mpc.el (mpc-cmd-find, mpc-cmd-move, mpc-select-extend) (mpc-songs-refresh, mpc-songpointer-score) (mpc-songpointer-refresh-hairy): * lisp/msb.el (msb--mode-menu-cond, msb--most-recently-used-menu) (msb--split-menus-2, msb--make-keymap-menu): * lisp/net/pop3.el (pop3-send-streaming-command): * lisp/net/puny.el (puny-encode-complex, puny-decode-string-internal): * lisp/net/shr-color.el (shr-color-hue-to-rgb): * lisp/net/soap-client.el (soap-encode-xs-complex-type) (soap-decode-xs-complex-type, soap-resolve-references-for-operation) (soap-wsdl-resolve-references): * lisp/play/5x5.el (5x5-made-move, 5x5-down, 5x5-right): * lisp/play/decipher.el (key, decipher-mode-syntax-table) (decipher-add-undo, decipher-complete-alphabet, decipher--analyze) (decipher--digram-counts, decipher--digram-total): * lisp/play/hanoi.el (hanoi-move-ring): * lisp/play/snake.el (snake-reset-game, snake-update-game): * lisp/profiler.el (profiler-calltree-depth, profiler-calltree-build-1) (profiler-calltree-build-unified) (profiler-calltree-compute-percentages): * lisp/registry.el (registry-reindex): * lisp/simple.el (completion-list-candidate-at-point): * lisp/strokes.el (strokes-xpm-to-compressed-string): * lisp/term.el (term-emulate-terminal, term--handle-colors-list): * lisp/treesit.el (treesit-node-index, treesit-indent-region): * lisp/url/url-cookie.el (url-cookie-parse-file-netscape): * lisp/url/url-dav.el (url-dav-file-name-completion): * lisp/url/url-queue.el (url-queue-setup-runners) (url-queue-run-queue): * lisp/wdired.el (wdired-finish-edit): * lisp/wid-edit.el (widget-move): * lisp/window-tool-bar.el (window-tool-bar-string): * lisp/winner.el (winner-undo): * lisp/xwidget.el (xwidget-webkit-isearch-forward) (xwidget-webkit-isearch-backward): Prefer incf to cl-incf. diff --git a/admin/syncdoc-type-hierarchy.el b/admin/syncdoc-type-hierarchy.el index c9266da1c45..e58675c6e3c 100644 --- a/admin/syncdoc-type-hierarchy.el +++ b/admin/syncdoc-type-hierarchy.el @@ -107,7 +107,7 @@ (insert "|\n||") (setq x 0)) do (insert (symbol-name child) " ") - do (cl-incf x (1+ child-len)) ) + do (incf x (1+ child-len)) ) do (insert "\n"))) (require 'org-table) (declare-function org-table-align "org") diff --git a/admin/unidata/unidata-gen.el b/admin/unidata/unidata-gen.el index c65d10b27aa..ac3328787f0 100644 --- a/admin/unidata/unidata-gen.el +++ b/admin/unidata/unidata-gen.el @@ -1004,7 +1004,7 @@ Property value is a symbol `o' (Open), `c' (Close), or `n' (None)." (dotimes (i (length vec)) (dolist (elt (aref vec i)) (if (symbolp elt) - (cl-incf (alist-get elt (cdr word-list) 0))))) + (incf (alist-get elt (cdr word-list) 0))))) (set-char-table-range table (cons start limit) vec)))))) (setq word-list (sort (cdr word-list) #'(lambda (x y) (> (cdr x) (cdr y))))) diff --git a/lisp/arc-mode.el b/lisp/arc-mode.el index b28669ca4cf..d3f75090fab 100644 --- a/lisp/arc-mode.el +++ b/lisp/arc-mode.el @@ -1692,7 +1692,7 @@ This doesn't recover lost files, it just undoes changes in the buffer itself." (t (+ (string-width uid) (string-width gid) 1))))) (if (> len maxidlen) (setq maxidlen len)))) (let ((size (archive--file-desc-size desc))) - (cl-incf totalsize size) + (incf totalsize size) (if (> size maxsize) (setq maxsize size)))) (let* ((sizelen (length (number-to-string maxsize))) (dash diff --git a/lisp/auth-source.el b/lisp/auth-source.el index 376c061cd19..2d4fd396942 100644 --- a/lisp/auth-source.el +++ b/lisp/auth-source.el @@ -852,7 +852,7 @@ while \(:host t) would find all host entries." (auth-source-specmatchp spec (cdr key))) ;; remove that key (password-cache-remove key) - (cl-incf count))) + (incf count))) password-data) count)) diff --git a/lisp/battery.el b/lisp/battery.el index 0f39b3f7087..240329e20a9 100644 --- a/lisp/battery.el +++ b/lisp/battery.el @@ -485,19 +485,19 @@ The following %-sequences are provided: (when (re-search-forward (rx "design capacity:" (+ space) battery--acpi-capacity eol) nil t) - (cl-incf design-capacity (string-to-number (match-string 1)))) + (incf design-capacity (string-to-number (match-string 1)))) (when (re-search-forward (rx "last full capacity:" (+ space) battery--acpi-capacity eol) nil t) - (cl-incf last-full-capacity (string-to-number (match-string 1)))) + (incf last-full-capacity (string-to-number (match-string 1)))) (when (re-search-forward (rx "design capacity warning:" (+ space) battery--acpi-capacity eol) nil t) - (cl-incf warn (string-to-number (match-string 1)))) + (incf warn (string-to-number (match-string 1)))) (when (re-search-forward (rx "design capacity low:" (+ space) battery--acpi-capacity eol) nil t) - (cl-incf low (string-to-number (match-string 1))))))) + (incf low (string-to-number (match-string 1))))))) (setq full-capacity (if (> last-full-capacity 0) last-full-capacity design-capacity)) (and capacity rate @@ -587,10 +587,10 @@ The following %-sequences are provided: (when (re-search-forward "POWER_SUPPLY_\\(CURRENT\\|POWER\\)_NOW=\\([0-9]*\\)$" nil t) - (cl-incf power-now - (* (string-to-number (match-string 2)) - (if (eq (char-after (match-beginning 1)) ?C) - voltage-now 1)))) + (incf power-now + (* (string-to-number (match-string 2)) + (if (eq (char-after (match-beginning 1)) ?C) + voltage-now 1)))) (goto-char (point-min)) (when (re-search-forward "POWER_SUPPLY_TEMP=\\([0-9]*\\)$" nil t) (setq temperature (match-string 1))) @@ -604,10 +604,10 @@ The following %-sequences are provided: (re-search-forward "POWER_SUPPLY_CHARGE_NOW=\\([0-9]*\\)$" nil t) (setq now-string (match-string 1))) - (cl-incf energy-full (* (string-to-number full-string) - voltage-now)) - (cl-incf energy-now (* (string-to-number now-string) - voltage-now))) + (incf energy-full (* (string-to-number full-string) + voltage-now)) + (incf energy-now (* (string-to-number now-string) + voltage-now))) ((and (goto-char (point-min)) (re-search-forward "POWER_SUPPLY_ENERGY_FULL=\\([0-9]*\\)$" nil t) @@ -615,8 +615,8 @@ The following %-sequences are provided: (re-search-forward "POWER_SUPPLY_ENERGY_NOW=\\([0-9]*\\)$" nil t) (setq now-string (match-string 1))) - (cl-incf energy-full (string-to-number full-string)) - (cl-incf energy-now (string-to-number now-string))))) + (incf energy-full (string-to-number full-string)) + (incf energy-now (string-to-number now-string))))) (unless (zerop power-now) (let ((remaining (if (string= charging-state "Discharging") energy-now diff --git a/lisp/calendar/parse-time.el b/lisp/calendar/parse-time.el index 00dbc459e3f..33c5815ba7b 100644 --- a/lisp/calendar/parse-time.el +++ b/lisp/calendar/parse-time.el @@ -63,10 +63,10 @@ letters, digits, plus or minus signs or colons." (while (< index end) (while (and (< index end) ;Skip invalid characters. (not (setq c (parse-time-string-chars (aref string index))))) - (cl-incf index)) + (incf index)) (setq start index all-digits (eq c ?0)) - (while (and (< (cl-incf index) end) ;Scan valid characters. + (while (and (< (incf index) end) ;Scan valid characters. (setq c (parse-time-string-chars (aref string index)))) (setq all-digits (and all-digits (eq c ?0)))) (if (<= index end) diff --git a/lisp/calendar/time-date.el b/lisp/calendar/time-date.el index 959c4f17571..ce8c668c8cd 100644 --- a/lisp/calendar/time-date.el +++ b/lisp/calendar/time-date.el @@ -541,13 +541,13 @@ changes in daylight saving time are not taken into account." seconds) ;; Years are simple. (when (decoded-time-year delta) - (cl-incf (decoded-time-year time) (decoded-time-year delta))) + (incf (decoded-time-year time) (decoded-time-year delta))) ;; Months are pretty simple, but start at 1 (for January). (when (decoded-time-month delta) (let ((new (+ (1- (decoded-time-month time)) (decoded-time-month delta)))) (setf (decoded-time-month time) (1+ (mod new 12))) - (cl-incf (decoded-time-year time) (/ new 12)))) + (incf (decoded-time-year time) (/ new 12)))) ;; Adjust for month length (as described in the doc string). (setf (decoded-time-day time) @@ -581,10 +581,10 @@ changes in daylight saving time are not taken into account." "Increase or decrease the month in TIME by 1." (if increase (progn - (cl-incf (decoded-time-month time)) + (incf (decoded-time-month time)) (when (> (decoded-time-month time) 12) (setf (decoded-time-month time) 1) - (cl-incf (decoded-time-year time)))) + (incf (decoded-time-year time)))) (decf (decoded-time-month time)) (when (zerop (decoded-time-month time)) (setf (decoded-time-month time) 12) @@ -594,7 +594,7 @@ changes in daylight saving time are not taken into account." "Increase or decrease the day in TIME by 1." (if increase (progn - (cl-incf (decoded-time-day time)) + (incf (decoded-time-day time)) (when (> (decoded-time-day time) (date-days-in-month (decoded-time-year time) (decoded-time-month time))) diff --git a/lisp/cedet/semantic/ede-grammar.el b/lisp/cedet/semantic/ede-grammar.el index 7d00e44f751..6ee4eb55e81 100644 --- a/lisp/cedet/semantic/ede-grammar.el +++ b/lisp/cedet/semantic/ede-grammar.el @@ -144,8 +144,8 @@ Lays claim to all -by.el, and -wy.el files." (src (ede-expand-filename obj fname)) ;; (csrc (concat (file-name-sans-extension src) ".elc")) ) - (cl-incf (if (eq (byte-recompile-file src nil 0) t) - comp utd))))) + (incf (if (eq (byte-recompile-file src nil 0) t) + comp utd))))) (oref obj source)) (message "All Semantic Grammar sources are up to date in %s" (eieio-object-name obj)) (cons comp utd))) diff --git a/lisp/dired.el b/lisp/dired.el index 90a70b057ec..aa766b6170e 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -1996,7 +1996,7 @@ Overlays could be added when some user options are enabled, e.g., (i 0)) (put-text-property opoint end 'invisible 'dired-hide-details-detail) (while (re-search-forward "[^ ]+" end t) - (when (member (cl-incf i) dired-hide-details-preserved-columns) + (when (member (incf i) dired-hide-details-preserved-columns) (put-text-property opoint (point) 'invisible nil)) (setq opoint (point))))) (let ((beg (point)) (end (save-excursion diff --git a/lisp/edmacro.el b/lisp/edmacro.el index 96a633fd667..b0ae2e9011a 100644 --- a/lisp/edmacro.el +++ b/lisp/edmacro.el @@ -560,7 +560,7 @@ doubt, use whitespace." (when (stringp macro) (cl-loop for i below (length macro) do (when (>= (aref rest-mac i) 128) - (cl-incf (aref rest-mac i) (- ?\M-\^@ 128))))) + (incf (aref rest-mac i) (- ?\M-\^@ 128))))) (while (not (eq (aref rest-mac 0) 'end-macro)) (let* ((prefix (or (and (integerp (aref rest-mac 0)) @@ -569,7 +569,7 @@ doubt, use whitespace." '(digit-argument negative-argument)) (let ((i 1)) (while (memq (aref rest-mac i) (cdr mdigs)) - (cl-incf i)) + (incf i)) (and (not (memq (aref rest-mac i) pkeys)) (prog1 (vconcat "M-" (cl-subseq rest-mac 0 i) " ") (cl-callf cl-subseq rest-mac i))))) @@ -577,7 +577,7 @@ doubt, use whitespace." (eq (key-binding [?\C-u]) 'universal-argument) (let ((i 1)) (while (eq (aref rest-mac i) ?\C-u) - (cl-incf i)) + (incf i)) (and (not (memq (aref rest-mac i) pkeys)) (prog1 (cl-loop repeat i concat "C-u ") (cl-callf cl-subseq rest-mac i))))) @@ -585,10 +585,10 @@ doubt, use whitespace." (eq (key-binding [?\C-u]) 'universal-argument) (let ((i 1)) (when (eq (aref rest-mac i) ?-) - (cl-incf i)) + (incf i)) (while (memq (aref rest-mac i) '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)) - (cl-incf i)) + (incf i)) (and (not (memq (aref rest-mac i) pkeys)) (prog1 (vconcat "C-u " (cl-subseq rest-mac 1 i) " ") (cl-callf cl-subseq rest-mac i))))))) @@ -685,8 +685,8 @@ doubt, use whitespace." (while (not (cl-mismatch rest-mac rest-mac :start1 0 :end1 bind-len :start2 pos :end2 (+ bind-len pos))) - (cl-incf times) - (cl-incf pos bind-len)) + (incf times) + (incf pos bind-len)) (when (> times 1) (setq desc (format "%d*%s" times desc)) (setq bind-len (* bind-len times))))) @@ -706,9 +706,9 @@ doubt, use whitespace." (setq len 1)) (unless (equal res "") (cl-callf concat res " ") - (cl-incf len))) + (incf len))) (cl-callf concat res desc) - (cl-incf len (length desc))))) + (incf len (length desc))))) res)) (defun edmacro-sanitize-for-string (seq) diff --git a/lisp/epa-file.el b/lisp/epa-file.el index b1767903954..729360449b1 100644 --- a/lisp/epa-file.el +++ b/lisp/epa-file.el @@ -250,8 +250,8 @@ encryption is used." (while (and (< p1 new-start) (< p2 (point-max)) (eql (char-after p1) (char-after p2))) - (cl-incf p1) - (cl-incf p2)) + (incf p1) + (incf p2)) (delete-region new-start p2) (delete-region p1 new-start))) ;; Restore point, if possible. diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index 8c582968dc5..f0c3a6a3e14 100644 --- a/lisp/eshell/esh-cmd.el +++ b/lisp/eshell/esh-cmd.el @@ -542,7 +542,7 @@ If ARGS is not a sequence, treat it as a list of one element." (cl-assert (and i end)) (while (< i end) (iter-yield i) - (cl-incf i)))) + (incf i)))) ((stringp arg) (iter-yield arg)) ((listp arg) diff --git a/lisp/eshell/esh-io.el b/lisp/eshell/esh-io.el index c4f7ebf12e0..11efb428799 100644 --- a/lisp/eshell/esh-io.el +++ b/lisp/eshell/esh-io.el @@ -345,7 +345,7 @@ calling this function)." (if stderr (let ((target (eshell-get-target stderr error-mode))) (cons (when target (list target)) 1)) - (cl-incf (cdr output-target)) + (incf (cdr output-target)) output-target))) (aset handles eshell-output-handle (list output-target t)) (aset handles eshell-error-handle (list error-target t)) @@ -366,7 +366,7 @@ is not shared with the original handles." (dotimes (idx eshell-number-of-handles) (when-let* ((handle (aref handles idx))) (unless steal-p - (cl-incf (cdar handle))) + (incf (cdar handle))) (aset dup-handles idx (list (car handle) t)))) dup-handles)) @@ -374,7 +374,7 @@ is not shared with the original handles." "Protect the handles in HANDLES from a being closed." (dotimes (idx eshell-number-of-handles) (when-let* ((handle (aref handles idx))) - (cl-incf (cdar handle)))) + (incf (cdar handle)))) handles) (declare-function eshell-exit-success-p "esh-cmd") @@ -442,7 +442,7 @@ If HANDLES is nil, use `eshell-current-handles'." (let* ((handles (or handles eshell-current-handles)) (handle-to-copy (car (aref handles index-to-copy)))) (when handle-to-copy - (cl-incf (cdr handle-to-copy))) + (incf (cdr handle-to-copy))) (eshell-close-handle (aref handles index) nil) (setcar (aref handles index) handle-to-copy))) @@ -527,8 +527,8 @@ When the buffer exceeds `eshell-buffered-print-size' in characters, this will flush it using `eshell-flush' (which see)." (setq eshell--buffered-print-queue (nconc eshell--buffered-print-queue strings)) - (cl-incf eshell--buffered-print-current-size - (apply #'+ (mapcar #'length strings))) + (incf eshell--buffered-print-current-size + (apply #'+ (mapcar #'length strings))) (when (> eshell--buffered-print-current-size eshell-buffered-print-size) (eshell-flush))) diff --git a/lisp/font-lock.el b/lisp/font-lock.el index 5746ae2a027..c846ed63c4d 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el @@ -1713,7 +1713,7 @@ LOUDLY, if non-nil, allows progress-meter bar." ;; Fontify each item in `font-lock-keywords' from `start' to `end'. (while keywords (if loudly (message "Fontifying %s... (regexps..%s)" bufname - (make-string (cl-incf count) ?.))) + (make-string (incf count) ?.))) ;; ;; Find an occurrence of `matcher' from `start' to `end'. (setq keyword (car keywords) matcher (car keyword)) diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 6112df99850..bbc7700c49e 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -958,7 +958,7 @@ TYPE indicates the namespace and is `fun' or `var'." ;; (let ((count 0)) ;; (obarray-map (lambda (sym) ;; (when (or (fboundp sym) (boundp sym)) -;; (cl-incf count))) +;; (incf count))) ;; obarray) ;; count)) ;; (p (make-progress-reporter "Check first releases..." 0 count))) @@ -971,7 +971,7 @@ TYPE indicates the namespace and is `fun' or `var'." ;; (obarray-map ;; (lambda (sym) ;; (when (or (fboundp sym) (boundp sym)) -;; (cl-incf count) +;; (incf count) ;; (progress-reporter-update p count) ;; (let ((vt (progn (setq quoted t) ;; (help-fns--first-release sym))) diff --git a/lisp/ibuf-ext.el b/lisp/ibuf-ext.el index 94742cded01..e57ac772ede 100644 --- a/lisp/ibuf-ext.el +++ b/lisp/ibuf-ext.el @@ -752,7 +752,7 @@ specification, with the same structure as an element of the list (hip-crowd (cdr (assq t res))) (lamers (cdr (assq nil res)))) (aset vec i hip-crowd) - (cl-incf i) + (incf i) (setq bmarklist lamers)))) (let (ret) (dotimes (j i) @@ -898,7 +898,7 @@ See also `ibuffer-kill-filter-group'." (if (equal (car groups) group) (setq found t groups nil) - (cl-incf res) + (incf res) (setq groups (cdr groups)))) res))) (cond ((not found) diff --git a/lisp/ibuffer.el b/lisp/ibuffer.el index bba8d554215..53cf62b142b 100644 --- a/lisp/ibuffer.el +++ b/lisp/ibuffer.el @@ -1119,7 +1119,7 @@ a new window in the current frame, splitting vertically." (setq trying nil)) (error ;; Handle a failure - (if (or (> (cl-incf attempts) 4) + (if (or (> (incf attempts) 4) (and (stringp (cadr err)) ;; This definitely falls in the ;; ghetto hack category... @@ -1917,18 +1917,18 @@ the buffer object itself and the current mark symbol." ;; nil if it chose not to affect the buffer ;; `kill' means the remove line from the buffer list ;; t otherwise - (cl-incf ibuffer-map-lines-total) + (incf ibuffer-map-lines-total) (cond ((null result) (forward-line 1)) ((eq result 'kill) (delete-region (line-beginning-position) (1+ (line-end-position))) - (cl-incf ibuffer-map-lines-count) + (incf ibuffer-map-lines-count) (when (< ibuffer-map-lines-total orig-target-line) (decf target-line-offset))) (t - (cl-incf ibuffer-map-lines-count) + (incf ibuffer-map-lines-count) (forward-line 1))))) ;; With `ibuffer-auto-mode' enabled, `ibuffer-expert' nil ;; and more than one marked buffer lines, the preceding loop diff --git a/lisp/image/image-dired-external.el b/lisp/image/image-dired-external.el index f09f676893d..51aa886507f 100644 --- a/lisp/image/image-dired-external.el +++ b/lisp/image/image-dired-external.el @@ -517,7 +517,7 @@ Number of simultaneous jobs is limited by `image-dired-queue-active-limit'." image-dired-queue-active-limit))) (while (and image-dired-queue (< image-dired-queue-active-jobs max-jobs)) - (cl-incf image-dired-queue-active-jobs) + (incf image-dired-queue-active-jobs) (apply #'image-dired-create-thumb-1 (pop image-dired-queue)))) ;; We are on MS-Windows with ImageMagick/GraphicsMagick, and need to ;; generate thumbnails by our lonesome selves. diff --git a/lisp/image/image-dired.el b/lisp/image/image-dired.el index aff452b0f5c..5bcf238e699 100644 --- a/lisp/image/image-dired.el +++ b/lisp/image/image-dired.el @@ -608,7 +608,7 @@ thumbnail buffer to be selected." (when (string-match-p (image-dired--file-name-regexp) file) (image-dired-insert-thumbnail (image-dired--get-create-thumbnail-file file) file dired-buf) - (cl-incf image-dired--number-of-thumbnails)))) + (incf image-dired--number-of-thumbnails)))) (if (plusp image-dired--number-of-thumbnails) (if do-not-pop (display-buffer buf) @@ -1216,9 +1216,9 @@ See also `image-dired-line-up-dynamic'." (forward-char) (if (= image-dired-thumbs-per-row 1) (insert "\n") - (cl-incf thumb-prev-pos thumb-width-chars) + (incf thumb-prev-pos thumb-width-chars) (insert (propertize " " 'display `(space :align-to ,thumb-prev-pos))) - (cl-incf seen) + (incf seen) (when (and (= seen (- image-dired-thumbs-per-row 1)) (not (eobp))) (forward-char) diff --git a/lisp/imenu.el b/lisp/imenu.el index f91fbff4300..0cf18447f62 100644 --- a/lisp/imenu.el +++ b/lisp/imenu.el @@ -391,7 +391,7 @@ The returned list DOES NOT share structure with LIST." (i 0)) (while remain (push (pop remain) sublist) - (cl-incf i) + (incf i) (and (= i n) ;; We have finished a sublist (progn (push (nreverse sublist) result) diff --git a/lisp/info-xref.el b/lisp/info-xref.el index 8637550c508..63df259c88f 100644 --- a/lisp/info-xref.el +++ b/lisp/info-xref.el @@ -259,11 +259,11 @@ buffer's line and column of point." ;; if the file exists, try the node (cond ((not (cdr (assoc file info-xref-xfile-alist))) - (cl-incf info-xref-unavail)) + (incf info-xref-unavail)) ((info-xref-goto-node-p node) - (cl-incf info-xref-good)) + (incf info-xref-good)) (t - (cl-incf info-xref-bad) + (incf info-xref-bad) (info-xref-output-error "No such node: %s" node))))))) @@ -482,8 +482,8 @@ and can take a long time." (if (eq :tag (cadr link)) (setq link (cddr link))) (if (info-xref-goto-node-p (cadr link)) - (cl-incf info-xref-good) - (cl-incf info-xref-bad) + (incf info-xref-good) + (incf info-xref-bad) ;; symbol-file gives nil for preloaded variables, would need ;; to copy what describe-variable does to show the right place (info-xref-output "Symbol `%s' (file %s): cannot goto node: %s" diff --git a/lisp/international/quail.el b/lisp/international/quail.el index daa55b14b87..2874d6cbe60 100644 --- a/lisp/international/quail.el +++ b/lisp/international/quail.el @@ -2419,10 +2419,10 @@ should be made by `quail-build-decode-map' (which see)." (let ((last-col-elt (or (nth (1- (* (1+ col) newrows)) single-list) (car (last single-list))))) - (cl-incf width (+ (max 3 (length (car last-col-elt))) + (incf width (+ (max 3 (length (car last-col-elt))) 1 single-trans-width 1)))) (< width window-width)) - (cl-incf cols)) + (incf cols)) (setq rows (/ (+ len cols -1) cols)) ;Round up. (let ((key-width (max 3 (length (car (nth (1- rows) single-list)))))) (insert "key") diff --git a/lisp/international/rfc1843.el b/lisp/international/rfc1843.el index 133d6f2b35c..f0bd8fb556f 100644 --- a/lisp/international/rfc1843.el +++ b/lisp/international/rfc1843.el @@ -116,15 +116,15 @@ e-mail transmission, news posting, etc." "Decode HZ WORD and return it." (let ((i -1) (s (substring word 0)) v) (if (or (not firstc) (eq firstc ?{)) - (while (< (cl-incf i) (length s)) + (while (< (incf i) (length s)) (if (eq (setq v (aref s i)) ? ) nil (aset s i (+ 128 v)))) - (while (< (cl-incf i) (length s)) + (while (< (incf i) (length s)) (if (eq (setq v (aref s i)) ? ) nil (setq v (+ (* 94 v) (aref s (1+ i)) -3135)) (aset s i (+ (/ v 157) (if (eq firstc ?<) 201 161))) (setq v (% v 157)) - (aset s (cl-incf i) (+ v (if (< v 63) 64 98)))))) + (aset s (incf i) (+ v (if (< v 63) 64 98)))))) s)) (provide 'rfc1843) diff --git a/lisp/mail/ietf-drums-date.el b/lisp/mail/ietf-drums-date.el index 0f79e9353d3..bbb27bd1f37 100644 --- a/lisp/mail/ietf-drums-date.el +++ b/lisp/mail/ietf-drums-date.el @@ -80,14 +80,14 @@ treat them as whitespace (per RFC822)." (or (> nest 0) (ietf-drums-date--ignore-char-p char) (and (not comment-eof) (eql char ?\()))) - (cl-incf index) + (incf index) ;; FWS bookkeeping. (cond ((and (eq char ?\\) (< (1+ index) end)) ;; Move to the next char but don't check ;; it to see if it might be a paren. - (cl-incf index)) - ((eq char ?\() (cl-incf nest)) + (incf index)) + ((eq char ?\() (incf nest)) ((eq char ?\)) (decf nest))))))) (skip-ignored) ;; Skip leading whitespace. (while (and (< index end) @@ -106,8 +106,8 @@ treat them as whitespace (per RFC822)." ;; RFC2?822 dates need escaping anyway, so it shouldn't ;; matter that this is not done strictly correctly. -- ;; rgr, 24-Dec-21. - (cl-incf index)) - (while (and (< (cl-incf index) end) + (incf index)) + (while (and (< (incf index) end) (setq char (aref string index)) (not (or (ietf-drums-date--ignore-char-p char) (eq char ?\()))) @@ -116,7 +116,7 @@ treat them as whitespace (per RFC822)." (when (and (eq char ?\\) (< (1+ index) end)) ;; Escaped character, see above. - (cl-incf index))) + (incf index))) (push (if all-digits (cl-parse-integer string :start start :end index) (substring string start index)) diff --git a/lisp/mail/ietf-drums.el b/lisp/mail/ietf-drums.el index a756d0e7d03..15638b24b35 100644 --- a/lisp/mail/ietf-drums.el +++ b/lisp/mail/ietf-drums.el @@ -86,7 +86,7 @@ backslash and doublequote.") b c out range) (while (< i (length token)) (setq c (aref token i)) - (cl-incf i) + (incf i) (cond ((eq c ?-) (if b @@ -95,7 +95,7 @@ backslash and doublequote.") (range (while (<= b c) (push (make-char 'ascii b) out) - (cl-incf b)) + (incf b)) (setq range nil)) ((= i (length token)) (push (make-char 'ascii c) out)) diff --git a/lisp/mail/rfc2047.el b/lisp/mail/rfc2047.el index 13d1ac320b0..66760a6595b 100644 --- a/lisp/mail/rfc2047.el +++ b/lisp/mail/rfc2047.el @@ -157,7 +157,7 @@ This is either `base64' or `quoted-printable'." (goto-char (point-min)) (skip-chars-forward "\x20-\x7f\r\n\t" limit) (while (< (point) limit) - (cl-incf n8bit) + (incf n8bit) (forward-char 1) (skip-chars-forward "\x20-\x7f\r\n\t" limit)) (if (or (< (* 6 n8bit) (- limit (point-min))) diff --git a/lisp/mail/rfc2231.el b/lisp/mail/rfc2231.el index 04527c78f8b..3426c909696 100644 --- a/lisp/mail/rfc2231.el +++ b/lisp/mail/rfc2231.el @@ -293,7 +293,7 @@ the result of this function." (insert param "*=") (while (not (eobp)) (insert (if (>= num 0) " " "") - param "*" (format "%d" (cl-incf num)) "*=") + param "*" (format "%d" (incf num)) "*=") (forward-line 1)))) (spacep (goto-char (point-min)) diff --git a/lisp/mail/yenc.el b/lisp/mail/yenc.el index 81cbab13b1f..ed7fb0fc6b2 100644 --- a/lisp/mail/yenc.el +++ b/lisp/mail/yenc.el @@ -97,14 +97,14 @@ (cond ((or (eq char ?\r) (eq char ?\n))) ((eq char ?=) - (setq char (char-after (cl-incf first))) + (setq char (char-after (incf first))) (with-current-buffer work-buffer (insert-char (mod (- char 106) 256) 1))) (t (with-current-buffer work-buffer ;;(insert-char (mod (- char 42) 256) 1) (insert-char (aref yenc-decoding-vector char) 1)))) - (cl-incf first)) + (incf first)) (setq bytes (buffer-size work-buffer)) (unless (and (= (cdr (assq 'size header-alist)) bytes) (= (cdr (assq 'size footer-alist)) bytes)) diff --git a/lisp/mh-e/mh-e.el b/lisp/mh-e/mh-e.el index ac13d3b2adb..e9e4e271065 100644 --- a/lisp/mh-e/mh-e.el +++ b/lisp/mh-e/mh-e.el @@ -463,7 +463,7 @@ all the strings have been used." (push (buffer-substring-no-properties (point) (line-end-position)) arg-list) - (cl-incf count) + (incf count) (forward-line)) (apply #'call-process cmd nil (list out nil) nil (nreverse arg-list)))) diff --git a/lisp/mh-e/mh-folder.el b/lisp/mh-e/mh-folder.el index 0f0cd88d212..5009c2c4f98 100644 --- a/lisp/mh-e/mh-folder.el +++ b/lisp/mh-e/mh-folder.el @@ -1472,7 +1472,7 @@ function doesn't recenter the folder buffer." (let ((lines-from-end 2)) (save-excursion (while (> (point-max) (progn (forward-line) (point))) - (cl-incf lines-from-end))) + (incf lines-from-end))) (recenter (- lines-from-end)))) ;; '(4) is the same as C-u prefix argument. (t (recenter (or arg '(4)))))) diff --git a/lisp/mh-e/mh-mime.el b/lisp/mh-e/mh-mime.el index 568d196ef05..00a6293ba70 100644 --- a/lisp/mh-e/mh-mime.el +++ b/lisp/mh-e/mh-mime.el @@ -750,7 +750,7 @@ buttons need to be displayed multiple times (for instance when nested messages are opened)." (or (gethash handle (mh-mime-part-index-hash (mh-buffer-data))) (setf (gethash handle (mh-mime-part-index-hash (mh-buffer-data))) - (cl-incf (mh-mime-parts-count (mh-buffer-data)))))) + (incf (mh-mime-parts-count (mh-buffer-data)))))) (defun mh-small-image-p (handle) "Decide whether HANDLE is a \"small\" image that can be displayed inline. diff --git a/lisp/mh-e/mh-search.el b/lisp/mh-e/mh-search.el index a0925684637..2dd50d3134a 100644 --- a/lisp/mh-e/mh-search.el +++ b/lisp/mh-e/mh-search.el @@ -287,7 +287,7 @@ folder containing the index search results." "-sequence" "cur" (format "%s" cur))) (cl-loop for msg in msgs - do (cl-incf result-count) + do (incf result-count) (setf (gethash result-count origin-map) (cons folder msg))))) folder-results-map) diff --git a/lisp/mh-e/mh-thread.el b/lisp/mh-e/mh-thread.el index f7ab461b924..d7d5b1828b1 100644 --- a/lisp/mh-e/mh-thread.el +++ b/lisp/mh-e/mh-thread.el @@ -248,7 +248,7 @@ sibling." (beginning-of-line) (forward-char address-start-offset) (while (char-equal (char-after) ? ) - (cl-incf level) + (incf level) (forward-char)) level))) diff --git a/lisp/mh-e/mh-utils.el b/lisp/mh-e/mh-utils.el index 1c6bc6833f0..205c13c849c 100644 --- a/lisp/mh-e/mh-utils.el +++ b/lisp/mh-e/mh-utils.el @@ -579,9 +579,9 @@ This function is a testable helper of `mh-sub-folders-actual'." (when (integerp has-pos) (while (equal (char-after has-pos) ? ) (decf has-pos)) - (cl-incf has-pos) + (incf has-pos) (while (equal (char-after start-pos) ? ) - (cl-incf start-pos)) + (incf start-pos)) (let* ((name (buffer-substring start-pos has-pos)) (first-char (aref name 0)) (second-char (and (length> name 1) (aref name 1))) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 0368e533dab..76061652161 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1758,7 +1758,7 @@ KEYFUN takes an element of ELEMS and should return a numerical value." (dolist (c hist) (unless (gethash c hash) (puthash c index hash)) - (cl-incf index)) + (incf index)) (minibuffer--sort-by-key elems (lambda (x) (gethash x hash most-positive-fixnum))))) @@ -4068,7 +4068,7 @@ Return nil if there's no such element." (i 0)) (dolist (x pattern) (unless (stringp x) - (cl-incf i) + (incf i) (if (eq x 'point) (setq idx i)))) idx)) diff --git a/lisp/mpc.el b/lisp/mpc.el index 9e63c76a323..7c96bdb3ac7 100644 --- a/lisp/mpc.el +++ b/lisp/mpc.el @@ -634,7 +634,7 @@ The songs are returned as alists." (i 0)) (mapcar (lambda (s) (prog1 (cons (cons 'Pos (number-to-string i)) s) - (cl-incf i))) + (incf i))) l))) ((eq tag 'Search) (mpc-proc-buf-to-alists @@ -870,7 +870,7 @@ If PLAYLIST is t or nil or missing, use the main playlist." (if (< song-pos dest-pos) ;; This move has shifted dest-pos by 1. (decf dest-pos)) - (cl-incf i))) + (incf i))) ;; Sort them from last to first, so the renumbering ;; caused by the earlier deletions affect ;; later ones a bit less. @@ -1420,12 +1420,12 @@ string POST." (while (and (zerop (forward-line 1)) (get-char-property (point) 'mpc-select)) (setq end (1+ (point))) - (cl-incf after)) + (incf after)) (goto-char mid) (while (and (zerop (forward-line -1)) (get-char-property (point) 'mpc-select)) (setq start (point)) - (cl-incf before)) + (incf before)) (if (and (= after 0) (= before 0)) ;; Shortening an already minimum-size region: do nothing. nil @@ -1449,13 +1449,13 @@ string POST." (start (line-beginning-position))) (while (and (zerop (forward-line 1)) (not (get-char-property (point) 'mpc-select))) - (cl-incf count)) + (incf count)) (unless (get-char-property (point) 'mpc-select) (setq count nil)) (goto-char start) (while (and (zerop (forward-line -1)) (not (get-char-property (point) 'mpc-select))) - (cl-incf before)) + (incf before)) (unless (get-char-property (point) 'mpc-select) (setq before nil)) (when (and before (or (null count) (< before count))) @@ -2063,7 +2063,7 @@ This is used so that they can be compared with `eq', which is needed for (cdr (assq 'file song1)) (cdr (assq 'file song2))))) (and (integerp cmp) (< cmp 0))))))) - (cl-incf totaltime (string-to-number (or (cdr (assq 'Time song)) "0"))) + (incf totaltime (string-to-number (or (cdr (assq 'Time song)) "0"))) (mpc-format mpc-songs-format song) (delete-char (- (skip-chars-backward " "))) ;Remove trailing space. (insert "\n") @@ -2305,12 +2305,12 @@ This is used so that they can be compared with `eq', which is needed for (dolist (song (car context)) (and (zerop (forward-line -1)) (eq (get-text-property (point) 'mpc-file) song) - (cl-incf count))) + (incf count))) (goto-char pos) (dolist (song (cdr context)) (and (zerop (forward-line 1)) (eq (get-text-property (point) 'mpc-file) song) - (cl-incf count))) + (incf count))) count)) (defun mpc-songpointer-refresh-hairy () @@ -2351,7 +2351,7 @@ This is used so that they can be compared with `eq', which is needed for ((< score context-size) nil) (t ;; Score is equal and increasing context might help: try it. - (cl-incf context-size) + (incf context-size) (let ((new-context (mpc-songpointer-context context-size plbuf))) (if (null new-context) diff --git a/lisp/msb.el b/lisp/msb.el index 6d8f976ee37..103f6ff838f 100644 --- a/lisp/msb.el +++ b/lisp/msb.el @@ -803,7 +803,7 @@ results in (defun msb--mode-menu-cond () (let ((key msb-modes-key)) (mapcar (lambda (item) - (cl-incf key) + (incf key) (list `( eq major-mode (quote ,(car item))) key (concat (cdr item) " (%d)"))) @@ -837,7 +837,7 @@ It takes the form ((TITLE . BUFFER-LIST)...)." buffer max-buffer-name-length) buffer)) - and do (cl-incf n) + and do (incf n) until (>= n msb-display-most-recently-used)))) (cons (if (stringp msb-most-recently-used-title) (format msb-most-recently-used-title @@ -1025,7 +1025,7 @@ variable `msb-menu-cond'." (tmp-list nil)) (while (< count msb-max-menu-items) (push (pop list) tmp-list) - (cl-incf count)) + (incf count)) (setq tmp-list (nreverse tmp-list)) (setq sub-name (concat (car (car tmp-list)) "...")) (push (nconc (list mcount sub-name @@ -1065,7 +1065,7 @@ variable `msb-menu-cond'." (cons (buffer-name (cdr item)) (cons (car item) 'msb--select-buffer))) (cdr sub-menu)))) - (nconc (list (cl-incf mcount) (car sub-menu) + (nconc (list (incf mcount) (car sub-menu) 'keymap (car sub-menu)) (msb--split-menus buffers)))))) raw-menu))) diff --git a/lisp/net/pop3.el b/lisp/net/pop3.el index a4de429311c..4d64cf153da 100644 --- a/lisp/net/pop3.el +++ b/lisp/net/pop3.el @@ -233,8 +233,8 @@ Use streaming commands." (setq start-point (pop3-wait-for-messages process pop3-stream-length total-size start-point)) - (cl-incf waited-for pop3-stream-length)) - (cl-incf i)) + (incf waited-for pop3-stream-length)) + (incf i)) (pop3-wait-for-messages process (- count waited-for) total-size start-point))) diff --git a/lisp/net/puny.el b/lisp/net/puny.el index 809e1832f07..456c0eefac3 100644 --- a/lisp/net/puny.el +++ b/lisp/net/puny.el @@ -114,7 +114,7 @@ For instance \"xn--bcher-kva\" => \"bücher\"." n m) (cl-loop for char across string when (< char n) - do (cl-incf delta) + do (incf delta) when (= char ijv) do (progn (setq q delta) @@ -137,8 +137,8 @@ For instance \"xn--bcher-kva\" => \"bücher\"." (setq bias (puny-adapt delta (+ h 1) (= h insertion-points)) delta 0 h (1+ h)))) - (cl-incf delta) - (cl-incf n)) + (incf delta) + (incf n)) (nreverse result))) (defun puny-decode-digit (cp) @@ -174,8 +174,8 @@ For instance \"xn--bcher-kva\" => \"bücher\"." digit t1) (cl-loop do (progn (setq digit (puny-decode-digit (aref encoded ic))) - (cl-incf ic) - (cl-incf i (* digit w)) + (incf ic) + (incf i (* digit w)) (setq t1 (cond ((<= k bias) puny-tmin) @@ -194,7 +194,7 @@ For instance \"xn--bcher-kva\" => \"bücher\"." (goto-char (point-min)) (forward-char i) (insert (format "%c" n)) - (cl-incf i))) + (incf i))) (buffer-string))) ;; https://www.unicode.org/reports/tr39/#Restriction_Level_Detection diff --git a/lisp/net/shr-color.el b/lisp/net/shr-color.el index 3f7b6f6df8f..bbb7bd6afaa 100644 --- a/lisp/net/shr-color.el +++ b/lisp/net/shr-color.el @@ -208,7 +208,7 @@ This will convert \"80 %\" to 204, \"100 %\" to 255 but \"123\" to \"123\"." (defun shr-color-hue-to-rgb (x y h) "Convert X Y H to RGB value." - (when (< h 0) (cl-incf h)) + (when (< h 0) (incf h)) (when (> h 1) (decf h)) (cond ((< h (/ 6.0)) (+ x (* (- y x) h 6))) ((< h 0.5) y) diff --git a/lisp/net/soap-client.el b/lisp/net/soap-client.el index 84c40895227..c4d816aa60a 100644 --- a/lisp/net/soap-client.el +++ b/lisp/net/soap-client.el @@ -1768,7 +1768,7 @@ This is a specialization of `soap-encode-value' for (let ((e-name (intern e-name))) (dolist (v value) (when (equal (car v) e-name) - (cl-incf instance-count) + (incf instance-count) (soap-encode-value (cdr v) candidate)))) (if (soap-xs-complex-type-indicator type) (let ((current-point (point))) @@ -1776,12 +1776,12 @@ This is a specialization of `soap-encode-value' for ;; characters were inserted in the buffer. (soap-encode-value value candidate) (when (not (equal current-point (point))) - (cl-incf instance-count))) + (incf instance-count))) (dolist (v value) (let ((current-point (point))) (soap-encode-value v candidate) (when (not (equal current-point (point))) - (cl-incf instance-count)))))))) + (incf instance-count)))))))) ;; Do some sanity checking (let* ((indicator (soap-xs-complex-type-indicator type)) (element-type (soap-xs-element-type element)) @@ -1997,7 +1997,7 @@ This is a specialization of `soap-decode-type' for (list node))) (element-type (soap-xs-element-type element))) (dolist (node children) - (cl-incf instance-count) + (incf instance-count) (let* ((attributes (soap-decode-xs-attributes element-type node)) ;; Attributes may specify xsi:type override. @@ -2316,7 +2316,7 @@ See also `soap-resolve-references' and (message (cdr input))) ;; Name this part if it was not named (when (or (null name) (equal name "")) - (setq name (format "in%d" (cl-incf counter)))) + (setq name (format "in%d" (incf counter)))) (when (soap-name-p message) (setf (soap-operation-input operation) (cons (intern name) @@ -2327,7 +2327,7 @@ See also `soap-resolve-references' and (let ((name (car output)) (message (cdr output))) (when (or (null name) (equal name "")) - (setq name (format "out%d" (cl-incf counter)))) + (setq name (format "out%d" (incf counter)))) (when (soap-name-p message) (setf (soap-operation-output operation) (cons (intern name) @@ -2339,7 +2339,7 @@ See also `soap-resolve-references' and (let ((name (car fault)) (message (cdr fault))) (when (or (null name) (equal name "")) - (setq name (format "fault%d" (cl-incf counter)))) + (setq name (format "fault%d" (incf counter)))) (if (soap-name-p message) (push (cons (intern name) (soap-wsdl-get message wsdl 'soap-message-p)) @@ -2425,19 +2425,19 @@ traverse an element tree." ;; If this namespace does not have an alias, create one for it. (catch 'done (while t - (setq nstag (format "ns%d" (cl-incf nstag-id))) + (setq nstag (format "ns%d" (incf nstag-id))) (unless (assoc nstag alias-table) (soap-wsdl-add-alias nstag (soap-namespace-name ns) wsdl) (throw 'done t))))) (maphash (lambda (_name element) (cond ((soap-element-p element) ; skip links - (cl-incf nprocessed) + (incf nprocessed) (soap-resolve-references element wsdl)) ((listp element) (dolist (e element) (when (soap-element-p e) - (cl-incf nprocessed) + (incf nprocessed) (soap-resolve-references e wsdl)))))) (soap-namespace-elements ns))))) wsdl) diff --git a/lisp/play/5x5.el b/lisp/play/5x5.el index 31b398a4bc1..159ed29adba 100644 --- a/lisp/play/5x5.el +++ b/lisp/play/5x5.el @@ -335,7 +335,7 @@ Quit current game \\[5x5-quit-game]" (defun 5x5-made-move () "Keep track of how many moves have been made." - (cl-incf 5x5-moves)) + (incf 5x5-moves)) (defun 5x5-make-random-grid (&optional move) "Make a random grid." @@ -865,7 +865,7 @@ lest." "Move down." (interactive nil 5x5-mode) (unless (= 5x5-y-pos (1- 5x5-grid-size)) - (cl-incf 5x5-y-pos) + (incf 5x5-y-pos) (5x5-position-cursor))) (defun 5x5-left () @@ -879,7 +879,7 @@ lest." "Move right." (interactive nil 5x5-mode) (unless (= 5x5-x-pos (1- 5x5-grid-size)) - (cl-incf 5x5-x-pos) + (incf 5x5-x-pos) (5x5-position-cursor))) (defun 5x5-bol () diff --git a/lisp/play/decipher.el b/lisp/play/decipher.el index 6b5a8d570db..ebcd50e736d 100644 --- a/lisp/play/decipher.el +++ b/lisp/play/decipher.el @@ -155,7 +155,7 @@ the tail of the list." (let ((key ?a)) (while (<= key ?z) (keymap-set decipher-mode-map (char-to-string key) #'decipher-keypress) - (cl-incf key))) + (incf key))) (defvar-keymap decipher-stats-mode-map :doc "Keymap for Decipher-Stats mode." @@ -170,7 +170,7 @@ the tail of the list." (c ?0)) (while (<= c ?9) (modify-syntax-entry c "_" table) ;Digits are not part of words - (cl-incf c)) + (incf c)) table) "Decipher mode syntax table.") @@ -373,7 +373,7 @@ The most useful commands are: (if undo-rec (progn (push undo-rec decipher-undo-list) - (cl-incf decipher-undo-list-size) + (incf decipher-undo-list-size) (if (> decipher-undo-list-size decipher-undo-limit) (let ((new-size (- decipher-undo-limit 100))) ;; Truncate undo list to NEW-SIZE elements: @@ -547,7 +547,7 @@ you have determined the keyword." (progn (while (rassoc cipher-char decipher-alphabet) ;; Find the next unused letter - (cl-incf cipher-char)) + (incf cipher-char)) (push (cons ?\s cipher-char) undo-rec) (decipher-set-map cipher-char (car plain-map) t)))) (decipher-add-undo undo-rec))) @@ -797,17 +797,17 @@ TOTAL is the total number of letters in the ciphertext." ;; A vector of 26 integers, counting the number of occurrences ;; of the corresponding characters. (setq decipher--digram (format "%c%c" decipher--prev-char decipher-char)) - (cl-incf (cdr (or (assoc decipher--digram decipher--digram-list) + (incf (cdr (or (assoc decipher--digram decipher--digram-list) (car (push (cons decipher--digram 0) decipher--digram-list))))) (and (>= decipher--prev-char ?A) - (cl-incf (aref (aref decipher--before (- decipher--prev-char ?A)) + (incf (aref (aref decipher--before (- decipher--prev-char ?A)) (if (equal decipher-char ?\s) 26 (- decipher-char ?A))))) (and (>= decipher-char ?A) - (cl-incf (aref decipher--freqs (- decipher-char ?A))) - (cl-incf (aref (aref decipher--after (- decipher-char ?A)) + (incf (aref decipher--freqs (- decipher-char ?A))) + (incf (aref (aref decipher--after (- decipher-char ?A)) (if (equal decipher--prev-char ?\s) 26 (- decipher--prev-char ?A))))) @@ -818,8 +818,8 @@ TOTAL is the total number of letters in the ciphertext." (let ((total 0)) (concat (mapconcat (lambda (x) - (cond ((> x 99) (cl-incf total) "XX") - ((> x 0) (cl-incf total) (format "%2d" x)) + (cond ((> x 99) (incf total) "XX") + ((> x 0) (incf total) (format "%2d" x)) (t " "))) counts "") @@ -835,7 +835,7 @@ TOTAL is the total number of letters in the ciphertext." (while (>= (decf i) 0) (if (or (> (aref before-count i) 0) (> (aref after-count i) 0)) - (cl-incf total))) + (incf total))) total)) (defun decipher-analyze-buffer () diff --git a/lisp/play/hanoi.el b/lisp/play/hanoi.el index 41e5de7c1f4..2b0a67105ef 100644 --- a/lisp/play/hanoi.el +++ b/lisp/play/hanoi.el @@ -337,7 +337,7 @@ BITS must be of length nrings. Start at START-TIME." ;; do one pole-to-pole move and update the ring and pole pairs. (defun hanoi-move-ring (ring from to start-time) - (cl-incf (car from) baseward-step) + (incf (car from) baseward-step) (decf (car to) baseward-step) (let* ;; We move flywards-steps steps up the pole to the fly row, ;; then fly fly-steps steps across the fly row, then go diff --git a/lisp/play/snake.el b/lisp/play/snake.el index c06e53047af..3a446db439c 100644 --- a/lisp/play/snake.el +++ b/lisp/play/snake.el @@ -269,8 +269,8 @@ and then start moving it leftwards.") (dotimes (_ snake-length) (gamegrid-set-cell x y snake-snake) (setq snake-positions (cons (vector x y) snake-positions)) - (cl-incf x snake-velocity-x) - (cl-incf y snake-velocity-y))) + (incf x snake-velocity-x) + (incf y snake-velocity-y))) (snake-update-score)) (defun snake-set-dot () @@ -296,8 +296,8 @@ Argument SNAKE-BUFFER is the name of the buffer." (= c snake-snake)) (snake-end-game) (cond ((= c snake-dot) - (cl-incf snake-length) - (cl-incf snake-score) + (incf snake-length) + (incf snake-score) (snake-update-score) (snake-set-dot)) (t diff --git a/lisp/profiler.el b/lisp/profiler.el index 57bd56af593..291bcb4a6b1 100644 --- a/lisp/profiler.el +++ b/lisp/profiler.el @@ -240,7 +240,7 @@ Optional argument MODE means only check for the specified mode (cpu or mem)." (defun profiler-calltree-depth (tree) (let ((d 0)) (while (setq tree (profiler-calltree-parent tree)) - (cl-incf d)) + (incf d)) d)) (defun profiler-calltree-find (tree entry) @@ -274,7 +274,7 @@ Optional argument MODE means only check for the specified mode (cpu or mem)." (setq child (profiler-make-calltree :entry entry :parent node)) (push child (profiler-calltree-children node))) - (cl-incf (profiler-calltree-count child) count) + (incf (profiler-calltree-count child) count) (setq node child))))))) log)) @@ -367,7 +367,7 @@ Optional argument MODE means only check for the specified mode (cpu or mem)." (push tmp parents) (setq tmp (cdr tmp))) (when (aref (cdar parents) (1- max)) - (cl-incf (profiler-calltree-count leftover-tree) count) + (incf (profiler-calltree-count leftover-tree) count) (setq node leftover-tree)) (pcase-dolist (`(,i . ,parent) parents) (let ((j (1- max))) @@ -380,7 +380,7 @@ Optional argument MODE means only check for the specified mode (cpu or mem)." (setq child (profiler-make-calltree :entry f :parent node)) (push child (profiler-calltree-children node))) - (cl-incf (profiler-calltree-count child) count) + (incf (profiler-calltree-count child) count) (setq node child))))))))) log))) @@ -388,7 +388,7 @@ Optional argument MODE means only check for the specified mode (cpu or mem)." (let ((total-count 0)) ;; FIXME: the memory profiler's total wraps around all too easily! (dolist (child (profiler-calltree-children tree)) - (cl-incf total-count (profiler-calltree-count child))) + (incf total-count (profiler-calltree-count child))) (unless (zerop total-count) (profiler-calltree-walk tree (lambda (node) diff --git a/lisp/registry.el b/lisp/registry.el index 520b8c1267e..3b489ea88b7 100644 --- a/lisp/registry.el +++ b/lisp/registry.el @@ -310,7 +310,7 @@ Errors out if the key exists already." (dolist (tr (oref db tracked)) (maphash (lambda (key v) - (cl-incf count) + (incf count) (when (and (< 0 expected) (= 0 (mod count 1000))) (message "reindexing: %d of %d (%.2f%%)" diff --git a/lisp/simple.el b/lisp/simple.el index c46b094f5a3..25c4bd36123 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -10256,7 +10256,7 @@ The optional argument PT defaults to (point)." (when (cond ((and (/= pt (point-max)) (get-text-property pt 'completion--string)) - (cl-incf pt)) + (incf pt)) ((and (/= pt (point-min)) (get-text-property (1- pt) 'completion--string)))) (setq pt (or (previous-single-property-change pt 'completion--string) pt)) diff --git a/lisp/strokes.el b/lisp/strokes.el index 4020538c942..10c88845fed 100644 --- a/lisp/strokes.el +++ b/lisp/strokes.el @@ -1561,7 +1561,7 @@ XPM-BUFFER defaults to \" *strokes-xpm*\"." ;; yet another of the same bit-type, so we continue ;; counting... (progn - (cl-incf count) + (incf count) (forward-char 1)) ;; otherwise, it's the opposite bit-type, so we do a ;; write and then restart count ### NOTE (for myself diff --git a/lisp/term.el b/lisp/term.el index a0ab2fc14e5..3f6b5c8f123 100644 --- a/lisp/term.el +++ b/lisp/term.el @@ -3110,7 +3110,7 @@ See `term-prompt-regexp'." (eq (char-charset (aref decoded-substring (- count 1 partial))) 'eight-bit)) - (cl-incf partial)) + (incf partial)) (when (> count partial 0) (setq term-terminal-undecoded-bytes (substring decoded-substring (- partial))) @@ -3487,7 +3487,7 @@ color is unset in the terminal state." (pcase (pop parameters) ;; 256 color (5 (if (setq term-ansi-current-color (pop parameters)) - (cl-incf term-ansi-current-color) + (incf term-ansi-current-color) (term-ansi-reset))) ;; Full 24-bit color (2 (cl-loop with color = (1+ 256) ; Base @@ -3517,7 +3517,7 @@ color is unset in the terminal state." (pcase (pop parameters) ;; 256 color (5 (if (setq term-ansi-current-bg-color (pop parameters)) - (cl-incf term-ansi-current-bg-color) + (incf term-ansi-current-bg-color) (term-ansi-reset))) ;; Full 24-bit color (2 (cl-loop with color = (1+ 256) ; Base diff --git a/lisp/treesit.el b/lisp/treesit.el index 6b7f54a04e7..97764e3ef80 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -426,7 +426,7 @@ If NAMED is non-nil, collect named child only." If NAMED is non-nil, count named child only." (let ((count 0)) (while (setq node (treesit-node-prev-sibling node named)) - (cl-incf count)) + (incf count)) count)) (defun treesit-node-field-name (node) @@ -2367,7 +2367,7 @@ Similar to `treesit-indent', but indent a region instead." (copy-marker anchor t))) ;; SET OFFSET. (setf (aref meta-vec (+ 1 (* idx meta-len))) offset)))) - (cl-incf idx) + (incf idx) (setq lines-left-to-move (forward-line 1))) ;; Now IDX = last valid IDX + 1. (goto-char starting-pos) diff --git a/lisp/url/url-cookie.el b/lisp/url/url-cookie.el index c4656c12e2d..c2cbdf131cd 100644 --- a/lisp/url/url-cookie.el +++ b/lisp/url/url-cookie.el @@ -112,7 +112,7 @@ i.e. 1970-1-1) are loaded as expiring one year from now instead." s)))) (key (nth 5 fields)) (val (nth 6 fields))) - (cl-incf n) + (incf n) ;;(message "adding <%s>=<%s> exp=<%s> dom=<%s> path=<%s> sec=%S" key val expires dom path secure) (url-cookie-store key val expires dom path secure) )) diff --git a/lisp/url/url-dav.el b/lisp/url/url-dav.el index 21ed8c5ab05..1d617ceb874 100644 --- a/lisp/url/url-dav.el +++ b/lisp/url/url-dav.el @@ -865,7 +865,7 @@ Returns nil if URL contains no name starting with FILE." (setq failed t))) (if failed (setq searching nil) - (cl-incf n))) + (incf n))) (substring (car matches) 0 n)))))) (defun url-dav-register-handler (op) diff --git a/lisp/url/url-queue.el b/lisp/url/url-queue.el index 48d2c7b0733..746648e0aa1 100644 --- a/lisp/url/url-queue.el +++ b/lisp/url/url-queue.el @@ -87,7 +87,7 @@ The variable `url-queue-timeout' sets a timeout." (cond ((or (url-queue-start-time entry) (url-queue-pre-triggered entry)) - (cl-incf running)) + (incf running)) ((not waiting) (setq waiting entry)))) (when (and waiting @@ -108,7 +108,7 @@ The variable `url-queue-timeout' sets a timeout." (dolist (entry url-queue) (cond ((url-queue-start-time entry) - (cl-incf running)) + (incf running)) ((not waiting) (setq waiting entry)))) (when (and waiting diff --git a/lisp/wdired.el b/lisp/wdired.el index c7409446b19..03cbf7131cf 100644 --- a/lisp/wdired.el +++ b/lisp/wdired.el @@ -527,7 +527,7 @@ non-nil means return old filename." (when files-renamed (pcase-let ((`(,errs . ,successful-renames) (wdired-do-renames files-renamed))) - (cl-incf errors errs) + (incf errors errs) ;; Some of the renames may fail -- in that case, don't mark an ;; already-existing file with the same name as renamed. (pcase-dolist (`(,file . _) wdired--old-marks) diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el index 38c8d34792a..84e1cec24bc 100644 --- a/lisp/wid-edit.el +++ b/lisp/wid-edit.el @@ -1341,7 +1341,7 @@ nothing is shown in the echo area." (when new (if (eq new old) (setq pos (point)) - (cl-incf tabable) + (incf tabable) (setq arg (cond (fwd (1- arg)) (bwd (1+ arg)))) (setq old new)))))) diff --git a/lisp/window-tool-bar.el b/lisp/window-tool-bar.el index 96726960fea..b8f84bd2da7 100644 --- a/lisp/window-tool-bar.el +++ b/lisp/window-tool-bar.el @@ -234,10 +234,10 @@ This is for when you want more customizations than the command (propertize " " 'invisible t)))) (mem2 (memory-use-counts))) (cl-mapl (lambda (l-init l0 l1) - (cl-incf (car l-init) (- (car l1) (car l0)))) + (incf (car l-init) (- (car l1) (car l0)))) window-tool-bar--memory-use-delta-step1 mem0 mem1) (cl-mapl (lambda (l-init l1 l2) - (cl-incf (car l-init) (- (car l2) (car l1)))) + (incf (car l-init) (- (car l2) (car l1)))) window-tool-bar--memory-use-delta-step2 mem1 mem2) (setf window-tool-bar-string--cache @@ -251,8 +251,8 @@ This is for when you want more customizations than the command '(:box (line-width 1))) (propertize " " 'display '(space :width (1)))) result)) - (cl-incf window-tool-bar--refresh-done-count)) - (cl-incf window-tool-bar--refresh-skipped-count)) + (incf window-tool-bar--refresh-done-count)) + (incf window-tool-bar--refresh-skipped-count)) window-tool-bar-string--cache) diff --git a/lisp/winner.el b/lisp/winner.el index e56ddf92965..a129417b08c 100644 --- a/lisp/winner.el +++ b/lisp/winner.el @@ -381,7 +381,7 @@ In other words, \"undo\" changes in window configuration." (setq winner-pending-undo-ring (winner-ring (selected-frame))) (setq winner-undo-counter 0) (setq winner-undone-data (list (winner-win-data)))) - (cl-incf winner-undo-counter) ; starting at 1 + (incf winner-undo-counter) ; starting at 1 (when (and (winner-undo-this) (not (window-minibuffer-p))) (message "Winner undo (%d / %d)" diff --git a/lisp/xwidget.el b/lisp/xwidget.el index a209e288f10..01f287c08ee 100644 --- a/lisp/xwidget.el +++ b/lisp/xwidget.el @@ -1090,7 +1090,7 @@ With argument, add COUNT copies of CHAR." (let ((i 0)) (while (< i count) (xwidget-webkit-next-result (xwidget-webkit-current-session)) - (cl-incf i))) + (incf i))) (xwidget-webkit-isearch--update t)) (defun xwidget-webkit-isearch-backward (count) @@ -1104,7 +1104,7 @@ With argument, add COUNT copies of CHAR." (let ((i 0)) (while (< i count) (xwidget-webkit-previous-result (xwidget-webkit-current-session)) - (cl-incf i))) + (incf i))) (xwidget-webkit-isearch--update t)) (defun xwidget-webkit-isearch-exit () commit e60103f130916a4632a108352360cb620c02e9f0 Author: Stefan Kangas Date: Wed Feb 26 01:48:48 2025 +0100 Prefer incf to cl-incf in vc/*.el * lisp/vc/diff-mode.el (diff-count-matches): (diff-fixup-modifs, diff-add-log-current-defuns): * lisp/vc/vc-hg.el (vc-hg--glob-to-pcre): * lisp/vc/vc-hooks.el (vc-insert-file): * lisp/vc/vc.el (vc-print-log-setup-buttons, vc-prepare-patch): Prefer incf to cl-incf. diff --git a/lisp/vc/diff-mode.el b/lisp/vc/diff-mode.el index 21a036bd139..40ec6121c3e 100644 --- a/lisp/vc/diff-mode.el +++ b/lisp/vc/diff-mode.el @@ -926,7 +926,7 @@ data such as \"Index: ...\" and such." (save-excursion (let ((n 0)) (goto-char start) - (while (re-search-forward re end t) (cl-incf n)) + (while (re-search-forward re end t) (incf n)) n))) (defun diff-splittable-p () @@ -1431,17 +1431,17 @@ else cover the whole buffer." "\\|[-*][-*][-*] [0-9,]+ [-*][-*][-*][-*]$" "\\|--- .+\n\\+\\+\\+ "))) (pcase (char-after) - (?\s (cl-incf space)) - (?+ (cl-incf plus)) + (?\s (incf space)) + (?+ (incf plus)) (?- (unless ;; In git format-patch "^-- $" signifies ;; the end of the patch. (and (eq diff-buffer-type 'git) (looking-at "^-- $")) - (cl-incf minus))) - (?! (cl-incf bang)) + (incf minus))) + (?! (incf bang)) ((or ?\\ ?#) nil) (?\n (if diff-valid-unified-empty-line - (cl-incf space) + (incf space) (setq space 0 plus 0 minus 0 bang 0))) (_ (setq space 0 plus 0 minus 0 bang 0))) (cond @@ -2692,9 +2692,9 @@ are relative to the root directory of the VC repository." (< (point) hunk-end)) (let ((patch-char (char-after))) (pcase patch-char - (?+ (cl-incf +lines)) - (?- (cl-incf -lines)) - (?\s (cl-incf =lines))) + (?+ (incf +lines)) + (?- (incf -lines)) + (?\s (incf =lines))) (save-current-buffer (funcall =ck-eodefun) (funcall +ck-eodefun) diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index afc31be8ef1..b4d7844013a 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -811,14 +811,14 @@ if we don't understand a construct, we signal (cl-macrolet ((peek () '(and (< i n) (aref glob i)))) (while (< i n) (setf c (aref glob i)) - (cl-incf i) + (incf i) (cond ((not (memq c '(?* ?? ?\[ ?\{ ?\} ?, ?\\))) (push (vc-hg--escape-for-pcre c) parts)) ((eq c ?*) (cond ((eq (peek) ?*) - (cl-incf i) + (incf i) (cond ((eq (peek) ?/) - (cl-incf i) + (incf i) (push "(?:.*/)?" parts)) (t (push ".*" parts)))) @@ -828,9 +828,9 @@ if we don't understand a construct, we signal ((eq c ?\[) (let ((j i)) (when (and (< j n) (memq (aref glob j) '(?! ?\]))) - (cl-incf j)) + (incf j)) (while (and (< j n) (not (eq (aref glob j) ?\]))) - (cl-incf j)) + (incf j)) (cond ((>= j n) (push "\\[" parts)) (t @@ -846,7 +846,7 @@ if we don't understand a construct, we signal (push x parts) (push ?\] parts)))))) ((eq c ?\{) - (cl-incf group) + (incf group) (push "(?:" parts)) ((eq c ?\}) (push ?\) parts) @@ -856,7 +856,7 @@ if we don't understand a construct, we signal ((eq c ?\\) (if (eq i n) (push "\\\\" parts) - (cl-incf i) + (incf i) (push ?\\ parts) (push c parts))) (t diff --git a/lisp/vc/vc-hooks.el b/lisp/vc/vc-hooks.el index e1513eed33a..7fd15bb1331 100644 --- a/lisp/vc/vc-hooks.el +++ b/lisp/vc/vc-hooks.el @@ -295,7 +295,7 @@ non-nil if FILE exists and its contents were successfully inserted." (let ((filepos 0)) (while (and (< 0 (cadr (insert-file-contents - file nil filepos (cl-incf filepos blocksize)))) + file nil filepos (incf filepos blocksize)))) (progn (beginning-of-line) (let ((pos (re-search-forward limit nil 'move))) (when pos (delete-region (match-beginning 0) diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index dc03bad3bcf..bc96173d198 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -2824,7 +2824,7 @@ or if PL-RETURN is `limit-unsupported'." (let ((entries 0)) (goto-char (point-min)) (while (re-search-forward log-view-message-re nil t) - (cl-incf entries)) + (incf entries)) (if (or (stringp limit) (< entries limit)) ;; The log has been printed in full. Perhaps it started @@ -3808,7 +3808,7 @@ marked revisions, use those." "text/x-patch" patch-subject "attachment" - (format "%04d-%s" (cl-incf i) filename)))))) + (format "%04d-%s" (incf i) filename)))))) (open-line 2))))) (defun vc-default-responsible-p (_backend _file) commit 1f891898d490380ea59f21fa8ea4e7f7364a1a79 Author: Pip Cet Date: Mon Feb 24 20:46:49 2025 +0000 Handle multibyte mode line spec chars (bug#76517) * src/xdisp.c (display_mode_element): Make 'c' an 'int'. Use 'string_char_and_length' to fetch the character from a multibyte string, not 'SREF'. diff --git a/src/xdisp.c b/src/xdisp.c index b6d9094e684..adc0f4d7e0a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -27755,7 +27755,7 @@ display_mode_element (struct it *it, int depth, int field_width, int precision, case Lisp_String: { /* A string: output it and check for %-constructs within it. */ - unsigned char c; + int c; ptrdiff_t offset = 0; if (SCHARS (elt) > 0 @@ -27926,6 +27926,15 @@ display_mode_element (struct it *it, int depth, int field_width, int precision, while ((c = SREF (elt, offset++)) >= '0' && c <= '9') field = field * 10 + c - '0'; + /* "%" could be followed by a multibyte character. */ + if (STRING_MULTIBYTE (elt)) + { + int length; + offset--; + c = string_char_and_length (SDATA (elt) + offset, &length); + offset += length; + } + /* Don't pad beyond the total padding allowed. */ if (field_width - n > 0 && field > field_width - n) field = field_width - n; commit 6f3067324aa83c0e6a44193c81a443d2c98e43d8 Author: Robert Pluim Date: Fri Feb 21 14:20:12 2025 +0100 Improve 'send-mail-function' defcustom. * lisp/mail/sendmail.el (send-mail-function): Provide better :doc for the available values. diff --git a/lisp/mail/sendmail.el b/lisp/mail/sendmail.el index 539a3780bb4..fda10cdfefe 100644 --- a/lisp/mail/sendmail.el +++ b/lisp/mail/sendmail.el @@ -151,12 +151,12 @@ not a valid RFC 822 (or later) header or continuation line, that matches the variable `mail-header-separator'. This is used by the default mail-sending commands. See also `message-send-mail-function' for use with the Message package." - :type '(radio (function-item sendmail-send-it) - (function-item sendmail-query-once) + :type '(radio (function-item :doc "Use the Sendmail package." sendmail-send-it) + (function-item :doc "Query once for which function to use (and remember it)." sendmail-query-once) (function-item :doc "Use SMTPmail package." smtpmail-send-it) - (function-item feedmail-send-it) - (function-item mailclient-send-it) - function) + (function-item :doc "Use Feedmail package." feedmail-send-it) + (function-item :doc "Use the system mail client." mailclient-send-it) + (function :tag "Custom function.")) :version "24.1") ;;;###autoload commit 5ea0cee19a7a4d88f92e6fab692a17ce295a6698 Author: Po Lu Date: Tue Feb 25 23:20:31 2025 +0800 Respect temporary-file-directory in Android test controller * test/infra/android/test-controller.el (ats-exec-script): Respect temporary-file-directory. diff --git a/test/infra/android/test-controller.el b/test/infra/android/test-controller.el index 999f66399e4..0df7725e574 100644 --- a/test/infra/android/test-controller.el +++ b/test/infra/android/test-controller.el @@ -452,7 +452,9 @@ as PACKAGE, provided that it is debuggable." (save-restriction (narrow-to-region (point) (point)) (let* ((name (format "%s.sh" (make-temp-name "ats-"))) - (fullname (concat (file-name-as-directory "/tmp") name))) + (fullname (concat (file-name-as-directory + temporary-file-directory) + name))) (with-temp-buffer (insert script) (write-region (point-min) (point-max) fullname)) commit c2d20946059bb78d7ab40060dbdc829c59a16bde Author: Michael Albinus Date: Tue Feb 25 15:50:35 2025 +0100 Fix bug in Tramp argument computing * lisp/net/tramp-sh.el (tramp-ssh-or-plink-options): Return always a string. (Bug#76553) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 2b0df59223a..84b0d97cd20 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -4951,7 +4951,10 @@ Goes through the list `tramp-inline-compress-commands'." ;; ControlPersist option is introduced in OpenSSH 5.6. (when (and (not (eq tramp-use-connection-share 'suppress)) (tramp-ssh-option-exists-p vec "ControlPersist=no")) - " -o ControlPersist=no"))))))) + " -o ControlPersist=no"))))) + + ;; Return a string, whatsoever. + (t ""))) (defun tramp-scp-strict-file-name-checking (vec) "Return the strict file name checking argument of the local scp." commit 55768eaaaac0702dea9bb686b932af24434c26cb Author: Po Lu Date: Tue Feb 25 22:34:43 2025 +0800 Implement commands for executing all tests on connected Android devices * test/infra/android/test-controller.el (ats-upload-test): Correct minor encoding error. Transfer solitary files without creating a tar archive, and handle `resources' directories. (ats-list-tests-locally, ats-list-tests): Don't list files in `resources' directories. Insert test header locally, and redisplay after insertion. (ats-run-all-tests): New function. diff --git a/test/infra/android/test-controller.el b/test/infra/android/test-controller.el index 711deca7d29..999f66399e4 100644 --- a/test/infra/android/test-controller.el +++ b/test/infra/android/test-controller.el @@ -2196,7 +2196,9 @@ Once uploaded, tests defined in the file may be loaded and executed by means of `ats-exec-tests'." (interactive (let* ((connection (ats-read-connection "Connection: ")) - (dir ats-emacs-test-directory) + (dir (or ats-emacs-test-directory + (read-directory-name "Test base directory: " + nil nil t))) (test (completing-read "Test to upload: " (ats-list-tests-locally dir) nil t nil @@ -2206,64 +2208,113 @@ executed by means of `ats-exec-tests'." (expand-file-name dir))) (test-file (concat dir-name test-name "-tests.el")) + (internal-resource-directory + (concat dir-name (file-name-directory test-name) + "resources")) (resources-directory - (concat dir-name test-name "-resources")) + (if (file-directory-p internal-resource-directory) + internal-resource-directory + (concat dir-name test-name "-resources"))) ;; Strip all directories from the test name. (default-directory (file-name-directory test-file))) (unless (file-regular-p test-file) (error "Not a regular file: %s" test-file)) - ;; Create a compressed tar file. Though a cpio implementation - ;; exists in the sources for Android 2.2's command line tools, yet - ;; it is often deleted in release builds of the OS to reduce storage - ;; utilization, so it is best to resort to tar and gzip, which Emacs - ;; is able to decompress without command line utilities. - (let ((temp-file (make-temp-file "ats-" nil ".tar"))) - (unwind-protect - (progn - (let ((bare-test-file (file-name-nondirectory test-file)) - (bare-test-resources (file-name-nondirectory test-file))) - (let ((rc (if (file-directory-p resources-directory) - (call-process "tar" nil nil nil "cf" temp-file - bare-test-file bare-test-resources) - (call-process "tar" nil nil nil "cf" temp-file - bare-test-file)))) - (unless (eq 0 rc) - (error "tar exited with code: %d" rc))) - ;; Compress this file. - (with-temp-buffer - (set-buffer-multibyte nil) - (let ((rc (call-process "gzip" temp-file '(t nil) nil - "-c" temp-file))) + (if (file-directory-p resources-directory) + ;; Create a compressed tar file. Though a cpio implementation + ;; exists in the sources for Android 2.2's command line tools, + ;; yet it is often deleted in release builds of the OS to reduce + ;; storage utilization, so it is best to resort to tar and gzip, + ;; which Emacs is able to decompress without command line + ;; utilities. + (let ((temp-file (make-temp-file "ats-" nil ".tar")) + (bare-test-file (file-name-nondirectory test-file)) + (bare-test-resources + (file-name-nondirectory resources-directory))) + (unwind-protect + (progn + (let ((rc (call-process + "tar" nil nil nil "cfh" temp-file + bare-test-file bare-test-resources))) (unless (eq 0 rc) - (error "gzip -c exited with code: %d" rc)) - ;; Write this compressed data to the destination and - ;; decompress it there. - (let ((rc (ats-eval - process - `(with-temp-buffer - (set-buffer-multibyte nil) - (insert ,(buffer-string)) - (zlib-decompress-region (point-min) - (point-max)) - (let ((dir - (concat (file-name-as-directory - temporary-file-directory) - "ats-tests/" ,test-name))) - (if (file-directory-p dir) - (let ((files (directory-files-recursively - dir "")) - (default-directory dir)) - (mapc #'delete-file files)) - (make-directory dir t)) - (let ((default-directory dir)) - (require 'tar-mode) - (tar-mode) - (tar-untar-buffer))))))) - (when (eq (car rc) 'error) - (error "Remote error: %S" (cdr rc))) - (message "Uploaded test `%s'" test-name)))))) - (with-demoted-errors "Removing temporary file: %S" - (delete-file temp-file)))))) + (error "tar exited with code: %d" rc))) + ;; Compress this file. + (with-temp-buffer + (set-buffer-multibyte nil) + (let ((rc (call-process "gzip" nil '(t nil) nil + "-c" temp-file))) + (unless (eq 0 rc) + (error "gzip -c exited with code: %d" rc)) + ;; Write this compressed data to the destination and + ;; decompress it there. + (let ((rc (ats-eval + process + `(with-temp-buffer + (set-buffer-multibyte nil) + (insert ,(buffer-string)) + (zlib-decompress-region (point-min) + (point-max)) + (let ((dir + (concat (file-name-as-directory + temporary-file-directory) + "ats-tests/" ,test-name))) + (if (file-directory-p dir) + (let ((files + (directory-files-recursively + dir "")) + (default-directory dir)) + (mapc #'delete-file files)) + (make-directory dir t)) + (let ((default-directory dir) + ;; Otherwise file name handlers + ;; such as `epa-file-handler' + ;; are liable to interfere with + ;; the extraction process. + (file-name-handler-alist nil)) + (require 'tar-mode) + (tar-mode) + (tar-untar-buffer)))) + nil t))) + (when (eq (car rc) 'error) + (error "Remote error: %S" (cdr rc))) + (message "Uploaded test `%s'" test-name))))) + (with-demoted-errors "Removing temporary file: %S" + (delete-file temp-file)))) + ;; Just compress and transfer the file alone. + (with-temp-buffer + (set-buffer-multibyte nil) + (let ((rc (call-process "gzip" nil '(t nil) nil + "-c" test-file))) + (unless (eq 0 rc) + (error "gzip -c exited with code: %d" rc)) + ;; Write this compressed data to the destination and + ;; decompress it there. + (let ((rc (ats-eval + process + `(with-temp-buffer + (set-buffer-multibyte nil) + (insert ,(buffer-string)) + (zlib-decompress-region (point-min) + (point-max)) + (let* ((dir + (concat (file-name-as-directory + temporary-file-directory) + "ats-tests/" ,test-name)) + (dir-1 (file-name-as-directory dir))) + (if (file-directory-p dir) + (let ((files + (directory-files-recursively + dir "")) + (default-directory dir)) + (mapc #'delete-file files)) + (make-directory dir t)) + (write-region + (point-min) (point-max) + (concat dir-1 ,(file-name-nondirectory + test-file))))) + nil t))) + (when (eq (car rc) 'error) + (error "Remote error: %S" (cdr rc))) + (message "Uploaded test `%s'" test-name))))))) (defun ats-list-tests-locally (dir) "Return a list of tests defined in DIR. @@ -2272,7 +2323,13 @@ a likewise structured directory tree." (let* ((default-directory (expand-file-name dir)) (start (length default-directory))) (let ((dirs (directory-files-recursively - dir "^[[:alnum:]-]+-tests\\.el$")) + dir "^[[:alnum:]-]+-tests\\.el$" + ;; Do not recurse into resource directories, as ERC's + ;; contain several files that resemble tests. + nil (lambda (dir-name) + (and (not (equal (file-name-nondirectory dir-name) + "resources")) + (not (string-suffix-p "-resources" dir-name)))))) tests) (dolist (dir dirs) (let ((len (length dir))) @@ -2304,6 +2361,7 @@ uploaded to the remote device represented by PROCESS, as by (lambda (dir) (let* ((name (file-name-nondirectory dir))) (and (not (funcall is-test-directory name dir)) + (not (equal name "resources")) (not (string-suffix-p name "-resources"))))))) (tests nil)) (dolist (dir dirs) @@ -2361,28 +2419,48 @@ Display the output of the tests executed in a buffer." (t (setq file-name (cdr rc)))) ;; Delete all tests, load the byte-compiled test file, and execute ;; those tests just defined subject to SELECTOR. - (setq rc (ats-eval process - `(progn - (require 'ert) - (ert-delete-all-tests) - (load ,file-name) - (with-temp-buffer - (let ((standard-output (current-buffer)) - (set-message-function - (lambda (message) - (insert message "\n")))) - (insert ,(format "=== Executing %s on %s ===\n" - test device)) - (let ((noninteractive t)) - (ert-run-tests-batch ',selector)) - (insert "=== Test execution complete ===\n") - (buffer-string)))))) - (cond ((eq (car rc) 'error) - (error "Error executing `%s-tests.el': %S" test (cdr rc))) - (t (with-current-buffer (get-buffer-create "*Test Output*") - (goto-char (point-max)) - (insert (cdr rc)) - (pop-to-buffer (current-buffer))))))) + (with-current-buffer (get-buffer-create "*Test Output*") + (insert (format "=== Executing %s on %s ===\n" test device)) + (redisplay) + (setq rc (ats-eval process + `(progn + (require 'ert) + (ert-delete-all-tests) + (load ,file-name) + (with-temp-buffer + (let ((standard-output (current-buffer)) + (set-message-function + (lambda (message) + (insert message "\n")))) + (let ((noninteractive t)) + (ert-run-tests-batch ',selector)) + (insert "=== Test execution complete ===\n") + (buffer-string)))))) + (cond ((eq (car rc) 'error) + (error "Error executing `%s-tests.el': %S" test (cdr rc))) + (t (progn + (goto-char (point-max)) + (insert (cdr rc)) + (pop-to-buffer (current-buffer)))))))) + +(defun ats-run-all-tests (process dir) + "Run all Emacs tests defined in DIR on the device represented by PROCESS. +Upload each and every test defined in DIR to the said device, +and execute them in sequence. With a prefix argument, just run +the tests without uploading them." + (interactive + (list (ats-read-connection "Connection: ") + (or ats-emacs-test-directory + (read-directory-name "Test base directory: " + nil nil t)))) + (let ((tests (ats-list-tests-locally dir))) + (unless current-prefix-arg + (dolist-with-progress-reporter (test tests) + "Uploading tests to device..." + (ats-upload-test process dir test))) + (dolist-with-progress-reporter (test tests) + "Running tests..." + (ats-run-test process test)))) (provide 'test-controller) commit 4101df53cc4d0bb5a913ce374206845d49336a15 Author: Robert Pluim Date: Fri Feb 14 16:57:36 2025 +0100 Remove unneded cl-extra require * lisp/international/emoji.el: Remove cl-extra require. diff --git a/lisp/international/emoji.el b/lisp/international/emoji.el index 55dd97ee6ec..fefce9d0bfb 100644 --- a/lisp/international/emoji.el +++ b/lisp/international/emoji.el @@ -28,7 +28,6 @@ ;;; Code: (require 'cl-lib) -(require 'cl-extra) (require 'transient) (require 'multisession) (require 'generate-lisp-file) commit 6a2dc0bbd93c56b8d3e3bd178735026140b76c36 Author: Robert Pluim Date: Fri Feb 14 16:56:28 2025 +0100 Remove wallpaper.el runtime dependency on cl-lib/cl-macs. * lisp/image/wallpaper.el: Don't require "cl-macs" unconditionally, instead require "cl-lib", only when compiling. diff --git a/lisp/image/wallpaper.el b/lisp/image/wallpaper.el index bee194246ca..821bf5c783d 100644 --- a/lisp/image/wallpaper.el +++ b/lisp/image/wallpaper.el @@ -56,7 +56,7 @@ (eval-when-compile (require 'subr-x)) (require 'xdg) -(require 'cl-macs) +(eval-when-compile (require 'cl-lib)) (defvar wallpaper-debug nil "If non-nil, display debug messages.") commit 68e49074f16b5fce4417bed83632c7540527a280 Merge: c8985a6d9fe 7da9d2d7464 Author: Michael Albinus Date: Tue Feb 25 12:41:12 2025 +0100 Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs commit c8985a6d9fe955c66bb24c910708957ed88afb55 Author: Michael Albinus Date: Tue Feb 25 12:40:33 2025 +0100 ; Fix last change * lisp/net/tramp-cmds.el (tramp-list-remote-buffers) (tramp-list-remote-buffer-connections): Fix docstring. (tramp-cleanup-bufferless-connections): Use `string-join'. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 7c1f0007dfb..0f9ffced90c 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -4802,7 +4802,6 @@ buffers, and buffers related to a remote process are cleaned up. @end defopt @deffn Command tramp-cleanup-bufferless-connections - Similar to @code{tramp-cleanup-all-connections}, remote connections and ad-hoc proxy definitions are flushed, but limited to those connections for which no associated buffers exist (except for Tramp internal diff --git a/lisp/net/tramp-cmds.el b/lisp/net/tramp-cmds.el index 5e7bface07b..cba300049ae 100644 --- a/lisp/net/tramp-cmds.el +++ b/lisp/net/tramp-cmds.el @@ -101,9 +101,9 @@ SYNTAX can be one of the symbols `default' (default), ;; Use `match-buffers' starting with Emacs 29.1. ;;;###tramp-autoload (defun tramp-list-remote-buffers () - "Return a list of remote buffers, excluding internal tramp buffers. -A buffer is considered remote if either its `default-directory' or its -buffer file name is a remote file name." + "Return a list of remote buffers, excluding internal Tramp buffers. +A buffer is considered remote if either its `default-directory' or +`buffer-file-name' is a remote file name." (tramp-compat-seq-keep (lambda (buffer) (when (tramp-tramp-file-p @@ -115,8 +115,8 @@ buffer file name is a remote file name." ;;;###tramp-autoload (defun tramp-list-remote-buffer-connections () "Return a list of all remote buffer connections. -A buffer is considered remote if either its `default-directory' or the -function `buffer-file-name' is a remote file name." +A buffer is considered remote if either its `default-directory' or +`buffer-file-name' is a remote file name." (seq-uniq (mapcar (lambda (buffer) (or @@ -124,7 +124,7 @@ function `buffer-file-name' is a remote file name." (file-remote-p (buffer-file-name buffer))) (when (tramp-get-default-directory buffer) (file-remote-p (tramp-get-default-directory buffer))))) - ;; Eliminate false positives from internal tramp buffers + ;; Eliminate false positives from internal Tramp buffers. (seq-remove (lambda (buffer) (member (buffer-name buffer) (tramp-list-tramp-buffers))) @@ -356,9 +356,10 @@ Display a message of cleaned-up connections." (seq-difference (mapcar #'tramp-make-tramp-file-name (tramp-list-connections)) (tramp-list-remote-buffer-connections)))) - (message "Cleaning up %s" (mapconcat #'identity bufferless-connections ", ")) + (message "Cleaning up %s" (string-join bufferless-connections ", ")) (dolist (connection bufferless-connections) - (tramp-cleanup-connection (tramp-dissect-file-name connection 'noexpand))))) + (tramp-cleanup-connection + (tramp-dissect-file-name connection 'noexpand))))) ;;; Rename commit 7da9d2d7464496ff684d28b0d37f286ddae70d65 Author: Po Lu Date: Tue Feb 25 19:12:37 2025 +0800 Fix a number of ERT tests for execution on Android * test/lib-src/emacsclient-tests.el (emacsclient-test-emacs): * test/lisp/server-tests.el (server-tests/emacsclient): Don't assume emacsclient is installed as emacsclient. diff --git a/test/lib-src/emacsclient-tests.el b/test/lib-src/emacsclient-tests.el index 54dd41c5a69..d65f79876db 100644 --- a/test/lib-src/emacsclient-tests.el +++ b/test/lib-src/emacsclient-tests.el @@ -30,7 +30,7 @@ (defconst emacsclient-test-emacs (if installation-directory (expand-file-name "lib-src/emacsclient" installation-directory) - "emacsclient") + emacsclient-program-name) "The emacsclient binary to test.") (defmacro emacsclient-test-call-emacsclient (editor) diff --git a/test/lisp/server-tests.el b/test/lisp/server-tests.el index 444c2f99fa7..aa124f099c7 100644 --- a/test/lisp/server-tests.el +++ b/test/lisp/server-tests.el @@ -44,7 +44,7 @@ like that, we just skip the test.") (defconst server-tests/emacsclient (if installation-directory (expand-file-name "lib-src/emacsclient" installation-directory) - "emacsclient") + emacsclient-program-name) "The emacsclient binary to test.") (defmacro server-tests/wait-until (form) commit 93a185a1fb874ebbcfdac257b50a3d0700a93fb5 Author: Po Lu Date: Tue Feb 25 19:12:06 2025 +0800 ; Improve Android regression test execution facilities * test/infra/android/test-controller.el (ats-associated-process): New variable. (ats-start-server): Set coding system to `no-conversion'. (ats-read-connection): If this buffer is associated with a connection, return the same. (ats-establish-connection): New arg INTERACTIVE. Interactively, open a Lisp interaction buffer with this connection as its associated process. (ats-connect): Provide this argument if called interactively. (ats-eval): New argument RAW. Request that encoded forms not be decoded if specified, and decode results. (ats-remote-eval-defuns, ats-remote-eval-print-sexp) (ats-remote-eval-for-interaction) (ats-remote-eval-print-last-sexp, ats-remote-eval-last-sexp) (ats-remote-eval-defun, ats-remote-eval-region-or-buffer) (ats-lisp-interaction-mode-map, ats-lisp-interaction-mode-menu) (ats-lisp-interaction-mode, ats-open-lisp-interaction-buffer) (ats-emacs-test-directory, ats-upload-test) (ats-list-tests-locally, ats-list-tests, ats-run-test): New functions and variables. * test/infra/android/test-driver.el (ats-eval-do-decode): New variable. (ats-process-filter, ats-establish-connection) (ats-initiate-connection): Adjust correspondingly. diff --git a/test/infra/android/test-controller.el b/test/infra/android/test-controller.el index e82b05d036f..711deca7d29 100644 --- a/test/infra/android/test-controller.el +++ b/test/infra/android/test-controller.el @@ -11,7 +11,7 @@ ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License @@ -1295,6 +1295,11 @@ DEVICE is the device where COMMFILE resides." (defvar ats-accepting-connection nil "UUID of connections being established.") +(defvar-local ats-associated-process nil + "ATS process associated with this buffer. +Such a process will be returned by `ats-read-connection' without +prompting the user.") + (defun ats-address-to-hostname (address) "Return the hostname component of the address ADDRESS." (progn @@ -1374,7 +1379,7 @@ Value is the port on which it will listen." t ats-default-port) :family 'ipv4 - :coding 'utf-8-emacs + :coding 'no-conversion :sentinel #'ats-server-sentinel :log #'ats-server-log))) (setq ats-server process) @@ -1613,15 +1618,21 @@ the same port." (defun ats-read-connection (prompt) "Read an ATS connection from the user, with completion. -PROMPT is the prompt displayed by `completing-read'. -Value is a process representing such a connection." - (let ((procs)) - (dolist (proc (process-list)) - (when (process-get proc 'ats-connection-details) - (push (buffer-name (process-buffer proc)) procs))) - (let ((buffer (completing-read prompt procs - nil t nil 'ats-read-processes))) - (get-buffer-process buffer)))) +If `ats-associated-process' is set in the current buffer, return +this process if it remains alive. PROMPT is the prompt +displayed by `completing-read'. Value is a process representing +such a connection." + (or (and ats-associated-process + (eq (process-status ats-associated-process) 'open) + ats-associated-process) + (let ((procs)) + (dolist (proc (process-list)) + (when (process-get proc 'ats-connection-details) + (push (buffer-name (process-buffer proc)) procs))) + (let ((buffer (completing-read prompt procs + nil t nil + 'ats-read-processes))) + (get-buffer-process buffer))))) (defun ats-disconnect (process) "Disconnect from the ATS connection represented by PROCESS. @@ -1633,7 +1644,7 @@ forwarding currently in place." (ats-in-connection-context (get-process process) details (delete-process process))) -(defun ats-establish-connection (process details) +(defun ats-establish-connection (process details &optional interactive) "Finalize a connection represented by PROCESS. DETAILS should be an alist of connection information to which `ats-adb-host' is appended, with the following keys: @@ -1662,6 +1673,9 @@ DETAILS should be an alist of connection information to which The port on the ADB host system mediating between the local and the remote system. +If INTERACTIVE, open a Lisp interaction buffer with +`ats-open-lisp-interaction-buffer'. + Value is PROCESS itself." (process-put process 'ats-connection-details (append `((host . ,ats-adb-host) @@ -1680,10 +1694,12 @@ Value is PROCESS itself." t))) (message "Connection established to %s (on %s)" (cdr (assq 'device details)) host)) - process) + (prog1 process + (when interactive + (ats-open-lisp-interaction-buffer process)))) ;;;###autoload -(defun ats-connect (device user &optional host) +(defun ats-connect (device user &optional host interactive) "Establish a connection to DEVICE on HOST executing as USER. HOST, if nil, defaults to `ats-adb-host'. If an instance of Emacs is already executing on DEVICE and the @@ -1718,7 +1734,7 @@ this machine and an SSH daemon be executing on the host)." user-alist nil t)))) (list device (or (cdr (assoc user user-alist)) (error "Unknown user: %s" user)) - host))) + host t))) ;; Terminate any existing instances of Emacs executing as this user. (let* ((ats-adb-host host) (emacs-aid (ats-get-package-aid device "org.gnu.emacs")) @@ -1798,7 +1814,8 @@ this machine and an SSH daemon be executing on the host)." (remote-port . ,remote-port) (host-port . ,host-port) (user . ,user) - (device . ,device)))))) + (device . ,device)) + interactive)))) ;; On failure, cease forwarding to this device, but permit ;; the connection to the host to remain. (unless process @@ -1841,7 +1858,7 @@ this machine and an SSH daemon be executing on the host)." :buffer name :host 'local :service local-port - :coding 'utf-8-emacs + :coding 'no-conversion :sentinel #'ats-server-sentinel)) (process-send-string process "-ok\n") (ats-establish-connection process @@ -1849,7 +1866,8 @@ this machine and an SSH daemon be executing on the host)." (local-port . ,local-port) (host-port . ,host-port) (user . ,user) - (device . ,device)))) + (device . ,device)) + interactive)) (error (when process ;; Finalize the failed process as best as can be @@ -1875,18 +1893,22 @@ this machine and an SSH daemon be executing on the host)." ;; (defvar ats-eval-tm 0) -(defun ats-eval (process form &optional as-printed) +(defun ats-eval (process form &optional as-printed raw) "Evaluate FORM in PROCESS, which form must be printable. Form should evaluate to a value that must be printable, or signal an error. Value is (ok . VALUE) if no error was -signaled, or (error . VALUE) otherwise. +signaled, or (error . VALUE) otherwise. If RAW, instruct +PROCESS not to attempt to decode the printed representation of +FORM as multibyte text; this does not influence the decoding +whatever value it returns. Set AS-PRINTED to insist that the value be returned as a string; this enables non-printable values to be returned in a meaningful manner." (ats-in-connection-context process details (save-restriction - (let* ((str (prin1-to-string form)) + (let* ((str (encode-coding-string + (prin1-to-string form) 'utf-8-emacs t)) (length (length str)) (serial (setf (alist-get 'eval-serial details) (1+ (alist-get 'eval-serial details)))) @@ -1897,9 +1919,10 @@ manner." (point (point)) size form) (process-send-string process - (format "-eval %d %d %s\n" serial + (format "-eval %d %d %s %s\n" serial length - (if as-printed "t" "nil"))) + (if as-printed "t" "nil") + (if raw "nil" "t"))) (process-send-string process str) ;; Read the resultant form. (while (not form) @@ -1923,9 +1946,444 @@ manner." (when (>= (- (point-max) (point-min)) size) (narrow-to-region (point-min) (+ (point-min) size)) (goto-char (point-min)) - (setq form (read (current-buffer))))))) + (setq form (car (read-from-string + (decode-coding-string + (buffer-string) + 'utf-8-unix t)))))))) form)))) + + +;; Remote Lisp Interaction mode. + +(defvar ats-remote-eval-defuns + '(progn + (defalias 'ats-remote-eval-on-device + #'(lambda (form) + "Remotely evaluate a submitted form FORM. +Collect FORM's standard output and return values, and return a +list of the form (ok STANDARD-OUTPUT VALUE VALUE-TRUNCATED), +where STANDARD-OUTPUT is any output the form has printed or +inserted, VALUE is FORM's value, and VALUE-TRUNCATED is FORM's +value after truncation as in the manner of `eval-expression', +both as strings. + +If FORM should signal an error, value becomes (error ERROR), +where ERROR is a cons of the error's symbol and of its data." + (condition-case error + (let ((standard-output + (get-buffer-create "*ats-standard-output*"))) + (with-current-buffer standard-output + (erase-buffer) + (let ((value (eval form nil))) + (list 'ok (buffer-string) + (prin1-to-string value) + (let ((print-length eval-expression-print-length) + (print-level eval-expression-print-level)) + (prin1-to-string value)))))) + (error (list 'error error)))))) + "Forms to be evaluated on the remote device before remote evaluation.") + +(defun ats-remote-eval-print-sexp + (value value-truncated output &optional no-truncate) + "Print VALUE and VALUE-TRUNCATED (a string) to OUTPUT. +The manner of printing is subject to NO-TRUNCATE. +Adapted from `elisp--eval-last-sexp-print-value' in +`elisp-mode.el'." + (let* ((unabbreviated value) (beg (point)) end) + (prog1 (princ (if no-truncate + value + value-truncated) + output) + (setq end (point)) + (when (and (bufferp output) + (or (not (null print-length)) + (not (null print-level))) + (not (string= unabbreviated + (buffer-substring-no-properties beg end)))) + (last-sexp-setup-props beg end value + unabbreviated + (buffer-substring-no-properties beg end)))))) + +(defun ats-remote-eval-for-interaction (process form &optional no-truncate) + "Evaluate FORM for Lisp interaction in a remote device. +PROCESS represents the connection to the said device. Insert +text printed by FORM to standard output and its return value on +success, as would `eval-last-sexp', and signal an error on +failure. +If NO-TRUNCATE, print FORM's value in full without truncation." + (let ((details (process-get process 'ats-connection-details)) + rc) + ;; First, set up a utility function. + (unless (cdr (assq 'remote-eval-initialized details)) + (setq rc (ats-eval process ats-remote-eval-defuns)) + (when (eq (car rc) 'error) + (error "Could not initialize remote evaluation: %S" + (cdr rc))) + (process-put process 'ats-connection-details + (cons '(remote-eval-initialized . t) details))) + ;; Next, really evaluate the form, and also, recognize and convert + ;; errors in preparing to evaluate the form appropriately. + (let ((value (ats-eval process + `(let ((eval-expression-print-length + ,eval-expression-print-length) + (eval-expression-print-level + ,eval-expression-print-level)) + (ats-remote-eval-on-device ',form))))) + (cond ((eq (car value) 'ok) + ;; The form was read successfully, but evaluation may + ;; nevertheless have terminated with an error. + (let ((value (cdr value))) + (cond ((eq (car value) 'ok) + (insert (cadr value)) + (ats-remote-eval-print-sexp (caddr value) + (cadddr value) + (current-buffer) + no-truncate)) + ((eq (car value) 'error) + (signal (caadr value) + (cdadr value)))))) + ((eq (car value) 'error) + ;; The device could not decode the form. + (error "Error decoding form on device: %S" (cdr value))))))) + +(defun ats-remote-eval-print-last-sexp (process &optional arg) + "Evaluate sexp before point; print value into the current buffer. +Evaluation transpires in the device controlled by the remote +connection represented by PROCESS. ARG inhibits truncation of +printed values, as in `eval-print-last-sexp'." + (interactive (list (ats-read-connection "Connection: ") + current-prefix-arg)) + (insert "\n") + (ats-remote-eval-for-interaction process (elisp--preceding-sexp) + arg) + (insert "\n")) + +(defun ats-remote-eval-last-sexp (process &optional arg) + "Evaluate sexp before point. +Subsequently, print value and inserted text in the echo area. +Evaluation transpires in the device controlled by the remote +connection represented by PROCESS. ARG inhibits truncation of +printed values, as in `eval-print-last-sexp'." + (interactive (list (ats-read-connection "Connection: ") + current-prefix-arg)) + (let ((sexp (elisp--preceding-sexp))) + (with-temp-buffer + (ats-remote-eval-for-interaction process sexp arg) + (message (buffer-string))))) + +(defun ats-remote-eval-defun (process) + "Evaluate defun around or after point. +Evaluation transpires in the device controlled by the remote +connection represented by PROCESS." + (interactive (list (ats-read-connection "Connection: "))) + (let ((standard-output t) form) + ;; Read the form from the buffer, and record where it ends. + (save-excursion + (end-of-defun) + (beginning-of-defun) + (setq form (read (current-buffer)))) + (with-temp-buffer + (ats-remote-eval-for-interaction process form) + (message (buffer-string))))) + +(defun ats-remote-eval-region-or-buffer (process) + "Evaluate the forms in the active region or the whole buffer. +Evaluation transpires in the device controlled by the remote +connection represented by PROCESS." + (interactive (list (ats-read-connection "Connection: "))) + (let ((evalstring (if (use-region-p) + (buffer-substring (region-beginning) + (region-end)) + (buffer-string)))) + (ats-eval process `(with-temp-buffer + (insert ,evalstring) + (eval-buffer))))) + +(defvar ats-lisp-interaction-mode-map + (let ((map (make-sparse-keymap))) + (define-key map [remap eval-print-last-sexp] + #'ats-remote-eval-print-last-sexp) + (define-key map [remap eval-defun] + #'ats-remote-eval-defun) + (define-key map [remap elisp-eval-region-or-buffer] + #'ats-remote-eval-region-or-buffer) + (define-key map [remap eval-last-sexp] + #'ats-remote-eval-last-sexp) + map) + "Keymap applied in `ats-lisp-interaction-mode' buffers.") + +(easy-menu-define ats-lisp-interaction-mode-menu + ats-lisp-interaction-mode-map + "Menu for Ats Lisp Interaction mode." + '("Lisp-Interaction" + ["Complete Lisp Symbol" completion-at-point + :help "Perform completion on Lisp symbol preceding point"] + ["Indent or Pretty-Print" indent-pp-sexp + :help "Indent each line of the list starting just after point, or prettyprint it"] + ["Evaluate and Print" ats-remote-eval-print-last-sexp + :help "Evaluate sexp before point; print value into current buffer"] + ["Evaluate Defun" ats-remote-eval-defun + :help "Evaluate the top-level form containing point, or after point"])) + +(define-derived-mode ats-lisp-interaction-mode lisp-interaction-mode + `("Remote Lisp Interaction" + (:eval (unless (and ats-associated-process + (processp ats-associated-process) + (eq (process-status ats-associated-process) + 'open)) + ,(propertize " disconnected" 'face 'error)))) + "Variant of `lisp-interaction-mode' that executes forms remotely. +This derivative of `lisp-interaction-mode' rebinds such commands +as \\[eval-print-last-sexp] to variants which submit forms for +execution on remote Android devices connected over `adb'. It +also disables a number of features unsupported by remote +execution facilities, such as edebug.") + +(defun ats-open-lisp-interaction-buffer (process) + "Open an Ats Lisp Interaction Mode buffer on PROCESS +Create and display a buffer in `ats-lisp-interaction-mode'; that +is, a mode akin to `lisp-interaction-mode' but which submits +forms typed to a remote Android device over the connection +represented by PROCESS." + (interactive (list (ats-read-connection "Connection: "))) + (ats-in-connection-context process details + (let ((device (cdr (assq 'device details))) + (user (cdr (assq 'user details)))) + (with-current-buffer (get-buffer-create + (format "*Lisp Interaction in %s (on %s%s)*" + device + (or ats-adb-host "localhost") + (if (not (eq user 0)) + (format ", as %d" user) + ""))) + (ats-lisp-interaction-mode) + (setq ats-associated-process process) + (when (eq (buffer-size) 0) + (insert (format "\ +;; This buffer enables typed Lisp forms to be executed in the device `%s' on `%s'. +;; View the doc string of `ats-lisp-interaction-mode' for specifics.\n\n" + device + (or ats-adb-host "localhost"))) + (save-excursion + (goto-char (point-min)) + (fill-region (point) (progn + (end-of-line) + (point))) + (goto-char (point-max)) + (beginning-of-line) + (fill-region (point) (point-max)))) + (pop-to-buffer (current-buffer)))))) + + +;; ERT regression testing. + +(defvar ats-emacs-test-directory + (and load-file-name + (expand-file-name + (concat (file-name-directory load-file-name) + "../../"))) + "Directory in which to locate Emacs regression tests, or nil otherwise.") + +(defun ats-upload-test (process dir test-name) + "Upload a test file and its resources to a remote device. +PROCESS represents the connection to the device. +TEST-NAME concatenated with \"-tests.el\" should identify a file +in DIR implementing a series of ERC regression tests. If there +is additionally a directory by the name TEST-NAME-resources in +the same directory, upload it to the remote device also. +Once uploaded, tests defined in the file may be loaded and +executed by means of `ats-exec-tests'." + (interactive + (let* ((connection (ats-read-connection "Connection: ")) + (dir ats-emacs-test-directory) + (test (completing-read "Test to upload: " + (ats-list-tests-locally dir) + nil t nil + 'ats-uploaded-tests))) + (list connection dir test))) + (let* ((dir-name (file-name-as-directory + (expand-file-name dir))) + (test-file + (concat dir-name test-name "-tests.el")) + (resources-directory + (concat dir-name test-name "-resources")) + ;; Strip all directories from the test name. + (default-directory (file-name-directory test-file))) + (unless (file-regular-p test-file) + (error "Not a regular file: %s" test-file)) + ;; Create a compressed tar file. Though a cpio implementation + ;; exists in the sources for Android 2.2's command line tools, yet + ;; it is often deleted in release builds of the OS to reduce storage + ;; utilization, so it is best to resort to tar and gzip, which Emacs + ;; is able to decompress without command line utilities. + (let ((temp-file (make-temp-file "ats-" nil ".tar"))) + (unwind-protect + (progn + (let ((bare-test-file (file-name-nondirectory test-file)) + (bare-test-resources (file-name-nondirectory test-file))) + (let ((rc (if (file-directory-p resources-directory) + (call-process "tar" nil nil nil "cf" temp-file + bare-test-file bare-test-resources) + (call-process "tar" nil nil nil "cf" temp-file + bare-test-file)))) + (unless (eq 0 rc) + (error "tar exited with code: %d" rc))) + ;; Compress this file. + (with-temp-buffer + (set-buffer-multibyte nil) + (let ((rc (call-process "gzip" temp-file '(t nil) nil + "-c" temp-file))) + (unless (eq 0 rc) + (error "gzip -c exited with code: %d" rc)) + ;; Write this compressed data to the destination and + ;; decompress it there. + (let ((rc (ats-eval + process + `(with-temp-buffer + (set-buffer-multibyte nil) + (insert ,(buffer-string)) + (zlib-decompress-region (point-min) + (point-max)) + (let ((dir + (concat (file-name-as-directory + temporary-file-directory) + "ats-tests/" ,test-name))) + (if (file-directory-p dir) + (let ((files (directory-files-recursively + dir "")) + (default-directory dir)) + (mapc #'delete-file files)) + (make-directory dir t)) + (let ((default-directory dir)) + (require 'tar-mode) + (tar-mode) + (tar-untar-buffer))))))) + (when (eq (car rc) 'error) + (error "Remote error: %S" (cdr rc))) + (message "Uploaded test `%s'" test-name)))))) + (with-demoted-errors "Removing temporary file: %S" + (delete-file temp-file)))))) + +(defun ats-list-tests-locally (dir) + "Return a list of tests defined in DIR. +DIR ought to be the `test' directory in the Emacs repository or +a likewise structured directory tree." + (let* ((default-directory (expand-file-name dir)) + (start (length default-directory))) + (let ((dirs (directory-files-recursively + dir "^[[:alnum:]-]+-tests\\.el$")) + tests) + (dolist (dir dirs) + (let ((len (length dir))) + (push (substring dir start (- len 9)) tests))) + (nreverse tests)))) + +(defun ats-list-tests (process) + "Enumerate those tests which have already been uploaded to PROCESS. +Return a list of strings identifying tests which have been +uploaded to the remote device represented by PROCESS, as by +`ats-upload-tests', and which may be executed with +`ats-exec-tests'." + (let ((rc (ats-eval + process + `(let* ((dir (concat (file-name-as-directory + temporary-file-directory) + "ats-tests")) + (len (length (file-name-as-directory dir))) + (default-directory dir) + (is-test-directory '(lambda (dir name) + (file-regular-p + (format "%s/%s-tests.el" + dir name))))) + (let ((dirs + (directory-files-recursively + dir "" t + ;; Do not iterate into directories that are tests of + ;; themselves, or their resources. + (lambda (dir) + (let* ((name (file-name-nondirectory dir))) + (and (not (funcall is-test-directory name dir)) + (not (string-suffix-p name "-resources"))))))) + (tests nil)) + (dolist (dir dirs) + (when (funcall is-test-directory + dir + (file-name-nondirectory dir)) + (push (substring dir len) tests))) + (nreverse tests)))))) + (when (eq (car rc) 'error) + (error "Remote error: %S" (cdr rc))) + (cdr rc))) + +(defun ats-run-test (process test &optional selector) + "Run tests defined in a single test TEST on a remote device. +PROCESS represents the device on which to execute these tests. +SELECTOR is an ERT test selector, as with `ert-select-tests'. +\(You may upload tests beforehand by calling `ats-upload-test'.) +Display the output of the tests executed in a buffer." + (interactive + (let* ((connection + (ats-read-connection "Connection: ")) + (test + (completing-read "Test to execute: " + (ats-list-tests connection) + nil t nil 'ats-tests-executed))) + (list connection test))) + ;; Attempt to byte-compile this test file. + (let ((rc (ats-eval + process + `(progn + (let* ((dir (concat (file-name-as-directory + temporary-file-directory) + "ats-tests/" ,test)) + (name ,(file-name-nondirectory test)) + (testfile (concat (file-name-as-directory dir) + name "-tests.el"))) + (with-temp-buffer + (let ((value (byte-compile-file testfile)) + (byte-compile-log-buffer (buffer-name))) + (cond ((eq value 'no-byte-compile) + testfile) + (value + (byte-compile-dest-file testfile)) + (t (list (buffer-string)))))))))) + (device (cdr (assq 'device (process-get + process 'ats-connection-details)))) + file-name) + (cond ((eq (car rc) 'error) + (error "Error during byte-compilation of `%s-tests.el': %S" + test (cdr rc))) + ((listp (cdr rc)) + (error + "Encountered errors byte-compiling `%s-tests.el':\n%s" + test (cadr rc))) + (t (setq file-name (cdr rc)))) + ;; Delete all tests, load the byte-compiled test file, and execute + ;; those tests just defined subject to SELECTOR. + (setq rc (ats-eval process + `(progn + (require 'ert) + (ert-delete-all-tests) + (load ,file-name) + (with-temp-buffer + (let ((standard-output (current-buffer)) + (set-message-function + (lambda (message) + (insert message "\n")))) + (insert ,(format "=== Executing %s on %s ===\n" + test device)) + (let ((noninteractive t)) + (ert-run-tests-batch ',selector)) + (insert "=== Test execution complete ===\n") + (buffer-string)))))) + (cond ((eq (car rc) 'error) + (error "Error executing `%s-tests.el': %S" test (cdr rc))) + (t (with-current-buffer (get-buffer-create "*Test Output*") + (goto-char (point-max)) + (insert (cdr rc)) + (pop-to-buffer (current-buffer))))))) + (provide 'test-controller) ;;; test-controller.el ends here diff --git a/test/infra/android/test-driver.el b/test/infra/android/test-driver.el index cebe5f032d7..78774176f02 100644 --- a/test/infra/android/test-driver.el +++ b/test/infra/android/test-driver.el @@ -1,5 +1,5 @@ ;;; Receive and execute Lisp code submitted by a test controller. -*- lexical-binding: t; -*- -;;; $Id: ats-driver.el,v 1.6 2025/02/19 01:56:55 jw Exp $ +;;; $Id: ats-driver.el,v 1.7 2025/02/25 07:58:35 jw Exp $ ;; Copyright (C) 2025 Free Software Foundation, Inc. @@ -52,6 +52,9 @@ (defvar-local ats-eval-serial nil "Serial number identifying this result.") +(defvar-local ats-eval-do-decode nil + "Whether to decode the form provided as utf-8-emacs.") + (defun ats-process-filter (process string) "Filter input from `ats-process'. Insert STRING into the connection buffer, till a full command is @@ -90,7 +93,7 @@ read." (error "Connection rejected; wanted ID=%s, received ID=%s" (match-string 2 command) (match-string 1 command))) ((string-match - "^-eval \\([[:digit:]]+\\) \\([[:digit:]]+\\) \\(t\\|nil\\)$" + "^-eval \\([[:digit:]]+\\) \\([[:digit:]]+\\) \\(t\\|nil\\) \\(t\\|nil\\)$" command) (setq ats-eval-serial (string-to-number (match-string 1 command)) @@ -98,45 +101,54 @@ read." (match-string 2 command)) ats-eval-as-printed (equal (match-string 3 command) - "t"))) + "t") + ats-eval-do-decode (equal + (match-string 4 command) + "t"))) (t (error (concat "Unknown command: " command)))))))) (when ats-in-eval ;; Proceed till `ats-in-eval' characters are read. (when (>= (- (point-max) (point-min)) ats-in-eval) - (let ((value - (save-restriction - (narrow-to-region (point-min) (1+ ats-in-eval)) - (condition-case err - (let* ((str (buffer-string))) - (with-current-buffer "*ATS*" - (goto-char (point-max)) - (let ((inhibit-read-only t)) - (insert "--> " (truncate-string-to-width - str 72) - "\n"))) - (let* ((expr (car (read-from-string str))) - (value (eval expr))) - (cons 'ok value))) - (error (cons 'error err)))))) - (let* ((print-escape-control-characters t) - (print-escape-newlines t) - (str (prin1-to-string value))) - (if ats-eval-as-printed - (let* ((quoted (prin1-to-string str))) + (unwind-protect + (let ((value + (save-restriction + (narrow-to-region (point-min) (1+ ats-in-eval)) + (condition-case err + (let* ((str (buffer-string))) + (with-current-buffer "*ATS*" + (goto-char (point-max)) + (let ((inhibit-read-only t)) + (insert "--> " (truncate-string-to-width + str 256) + "\n"))) + (let* ((str (if ats-eval-do-decode + (decode-coding-string + str 'utf-8-emacs t) + str)) + (expr (car (read-from-string str))) + (value (eval expr))) + (cons 'ok value))) + (t (cons 'error err)))))) + (let* ((print-escape-control-characters t) + (print-escape-newlines t) + (str (encode-coding-string + (prin1-to-string value) 'utf-8-emacs t))) + (if ats-eval-as-printed + (let* ((quoted (prin1-to-string str))) + (process-send-string + process (format "\fats-request:%d %d\n" + ats-eval-serial + (length quoted))) + (process-send-string process quoted)) (process-send-string process (format "\fats-request:%d %d\n" ats-eval-serial - (length quoted))) - (process-send-string process quoted)) - (process-send-string - process (format "\fats-request:%d %d\n" - ats-eval-serial - (length str))) - (process-send-string process str))) - (process-send-string process "\n")) - (delete-region (point-min) - (+ (point-min) ats-in-eval)) - (setq ats-in-eval nil))) + (length str))) + (process-send-string process str))) + (process-send-string process "\n")) + (delete-region (point-min) + (+ (point-min) ats-in-eval)) + (setq ats-in-eval nil)))) ;; Don't loop if the form data is yet to arrive. (setq firstchar (char-after (point-min)) in-eval nil)))))) @@ -170,7 +182,7 @@ failure." :buffer "*ats connection*" :host host :service port - :coding 'utf-8-emacs + :coding 'no-conversion :filter #'ats-process-filter)) (process-send-string ats-process (concat id "\n"))) @@ -191,7 +203,7 @@ the controller." :host 'local :service t :family 'ipv4 - :coding 'utf-8-emacs + :coding 'no-conversion :log #'ats-driver-log)) (service (process-contact process :service))) (with-temp-buffer commit bea00a07990ebfbe420636363f8d3514571ae79d Author: shipmints Date: Tue Feb 25 11:34:49 2025 +0100 Add tramp-cleanup-bufferless-connections (bug#76417) * doc/misc/tramp.texi (Cleanup remote connections): Add 'tramp-cleanup-bufferless-connections'. * etc/NEWS: Announce 'tramp-cleanup-bufferless-connections'. * lisp/net/tramp-cmds.el: (tramp-list-remote-buffer-connections): New function. (tramp-cleanup-bufferless-connections): New command. (tramp-list-remote-buffers): Account for 'buffer-file-name'. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 1eed1acd964..7c1f0007dfb 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -4783,13 +4783,13 @@ proxy definitions (@pxref{Ad-hoc multi-hops}). @deffn Command tramp-cleanup-all-buffers Just as for @code{tramp-cleanup-all-connections}, all remote -connections and ad-hoc proxy definition are cleaned up in addition to +connections and ad-hoc proxy definitions are cleaned up in addition to killing all buffers related to remote connections. @end deffn @deffn Command tramp-cleanup-some-buffers Similar to @code{tramp-cleanup-all-buffers}, where all remote -connections and ad-hoc proxy definition are cleaned up. However, +connections and ad-hoc proxy definitions are cleaned up. However, additional buffers are killed only if one of the functions in @code{tramp-cleanup-some-buffers-hook} returns @code{t}. @end deffn @@ -4801,6 +4801,19 @@ remote buffers which are linked to a remote file, remote @code{dired} buffers, and buffers related to a remote process are cleaned up. @end defopt +@deffn Command tramp-cleanup-bufferless-connections + +Similar to @code{tramp-cleanup-all-connections}, remote connections and +ad-hoc proxy definitions are flushed, but limited to those connections +for which no associated buffers exist (except for Tramp internal +buffers). + +This command is helpful to prune connections after you close remote-file +buffers without having to either cherry pick via +@code{tramp-cleanup-connection} or clear them all via +@code{tramp-cleanup-all-connections}. +@end deffn + @node Renaming remote files @section Renaming remote files diff --git a/etc/NEWS b/etc/NEWS index a86c2ca2409..7a5b96b5eae 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -950,6 +950,14 @@ we invite Flyspell users to enable this new option and report issues. ** Tramp ++++ +*** New command 'tramp-cleanup-bufferless-connections'. +Connection-related objects for which no associated buffers exist, except +for Tramp internal buffers, are flushed. This is helpful to prune +connections after you close remote-file buffers without having to either +cherry pick via 'tramp-cleanup-connection' or clear them all via +'tramp-cleanup-all-connections'. + +++ *** Connection method "kubernetes" supports now optional namespace. The host name for Kubernetes connections can be of kind diff --git a/lisp/net/tramp-cmds.el b/lisp/net/tramp-cmds.el index 71829e81093..5e7bface07b 100644 --- a/lisp/net/tramp-cmds.el +++ b/lisp/net/tramp-cmds.el @@ -101,12 +101,35 @@ SYNTAX can be one of the symbols `default' (default), ;; Use `match-buffers' starting with Emacs 29.1. ;;;###tramp-autoload (defun tramp-list-remote-buffers () - "Return a list of all buffers with remote `default-directory'." + "Return a list of remote buffers, excluding internal tramp buffers. +A buffer is considered remote if either its `default-directory' or its +buffer file name is a remote file name." (tramp-compat-seq-keep - (lambda (x) - (when (tramp-tramp-file-p (tramp-get-default-directory x)) x)) + (lambda (buffer) + (when (tramp-tramp-file-p + (or (buffer-file-name buffer) + (tramp-get-default-directory buffer))) + buffer)) (buffer-list))) +;;;###tramp-autoload +(defun tramp-list-remote-buffer-connections () + "Return a list of all remote buffer connections. +A buffer is considered remote if either its `default-directory' or the +function `buffer-file-name' is a remote file name." + (seq-uniq + (mapcar (lambda (buffer) + (or + (when (buffer-file-name buffer) + (file-remote-p (buffer-file-name buffer))) + (when (tramp-get-default-directory buffer) + (file-remote-p (tramp-get-default-directory buffer))))) + ;; Eliminate false positives from internal tramp buffers + (seq-remove + (lambda (buffer) + (member (buffer-name buffer) (tramp-list-tramp-buffers))) + (tramp-list-remote-buffers))))) + ;;; Cleanup ;;;###tramp-autoload @@ -321,6 +344,22 @@ non-nil." (let ((tramp-cleanup-some-buffers-hook '(always))) (tramp-cleanup-some-buffers))) +;;;###tramp-autoload +(defun tramp-cleanup-bufferless-connections () + "Flush connection-related objects for which no buffer exists. +A bufferless connection is one for which no live buffer's +`buffer-file-name' or `default-directory' is associated with that +connection, except for Tramp internal buffers. +Display a message of cleaned-up connections." + (interactive) + (when-let* ((bufferless-connections + (seq-difference + (mapcar #'tramp-make-tramp-file-name (tramp-list-connections)) + (tramp-list-remote-buffer-connections)))) + (message "Cleaning up %s" (mapconcat #'identity bufferless-connections ", ")) + (dolist (connection bufferless-connections) + (tramp-cleanup-connection (tramp-dissect-file-name connection 'noexpand))))) + ;;; Rename (defcustom tramp-default-rename-alist nil commit cc8e8b2595ff2ad0c4e4d5805fed1657a5ad504a Author: Michael Albinus Date: Tue Feb 25 09:57:30 2025 +0100 * doc/misc/ert.texi (Helpers for Buffers): Fix wrong name. diff --git a/doc/misc/ert.texi b/doc/misc/ert.texi index 116631ce727..2327cc94b29 100644 --- a/doc/misc/ert.texi +++ b/doc/misc/ert.texi @@ -1125,7 +1125,7 @@ This has the same effect as combining @code{ert-with-test-buffer} with @lisp (ert-deftest whitespace-tests--global () - (ert-with-test-buffer-selected (:name "global" :selected t) + (ert-with-test-buffer (:name "global" :selected t) @dots{})) @end lisp @end defmac commit 53eec34da1bf2fb9381680734a99f3fb11225787 Author: Michael Albinus Date: Tue Feb 25 09:37:28 2025 +0100 Fix tramp-find-executable * lisp/net/tramp-sh.el (tramp-find-executable): Use "command -pv", it isbetter supported in different shells. (Bug#76521) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 3468ea060d7..2b0df59223a 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -4091,25 +4091,23 @@ only in DIRLIST. Returns the absolute file name of PROGNAME, if found, and nil otherwise. This function expects to be in the right *tramp* buffer." - (with-current-buffer (tramp-get-connection-buffer vec) - (unless ignore-path - (setq dirlist (cons "$PATH" dirlist))) - (when ignore-tilde - ;; Remove all ~/foo directories from dirlist. - (let (newdl d) - (while dirlist - (setq d (car dirlist) - dirlist (cdr dirlist)) - (unless (char-equal ?~ (aref d 0)) - (setq newdl (cons d newdl)))) - (setq dirlist (nreverse newdl)))) - (tramp-send-command - vec (format "%s type -P %s 2>%s" - (if dirlist (concat "PATH=" (string-join dirlist ":")) "") - progname (tramp-get-remote-null-device vec))) - (goto-char (point-min)) - (when (search-forward-regexp "/" nil 'noerror) - (string-trim (buffer-substring (match-beginning 0) (point-max)))))) + (unless ignore-path + (setq dirlist (cons "$PATH" dirlist))) + (when ignore-tilde + ;; Remove all ~/foo directories from dirlist. + (let (newdl d) + (while dirlist + (setq d (car dirlist) + dirlist (cdr dirlist)) + (unless (char-equal ?~ (aref d 0)) + (setq newdl (cons d newdl)))) + (setq dirlist (nreverse newdl)))) + (when (tramp-send-command-and-check + vec (format "(unalias %s; %s command -pv %s)" + progname + (if dirlist (concat "PATH=" (string-join dirlist ":")) "") + progname)) + (string-trim (tramp-get-buffer-string (tramp-get-connection-buffer vec))))) ;; On hydra.nixos.org, the $PATH environment variable is too long to ;; send it. This is likely not due to PATH_MAX, but PIPE_BUF. We commit 41837050181a7cc313f1e9951136f4356601fc4a Author: Gerd Möllmann Date: Tue Feb 25 09:23:58 2025 +0100 Improve menu-bar-item-at-x * lisp/menu-bar.el (menu-bar-item-at-x): Handle case of duplicate keys in the menu-bar definition. diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index 13911109fd7..1b2a4f21a8b 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -2900,24 +2900,27 @@ returns nil." (menu-bar (menu-bar-keymap)) prev-key prev-column + keys-seen found) (catch 'done (map-keymap (lambda (key binding) - (when (> column x-position) - (setq found t) - (throw 'done nil)) - (setq prev-key key) - (pcase binding - ((or `(,(and (pred stringp) name) . ,_) ;Simple menu item. - `(menu-item ,name ,_cmd ;Extended menu item. - . ,(and props - (guard (let ((visible - (plist-get props :visible))) - (or (null visible) - (eval visible))))))) - (setq prev-column column - column (+ column (length name) 1))))) + (unless (memq key keys-seen) + (push key keys-seen) + (when (> column x-position) + (setq found t) + (throw 'done nil)) + (setq prev-key key) + (pcase binding + ((or `(,(and (pred stringp) name) . ,_) ;Simple menu item. + `(menu-item ,name ,_cmd ;Extended menu item. + . ,(and props + (guard (let ((visible + (plist-get props :visible))) + (or (null visible) + (eval visible))))))) + (setq prev-column column + column (+ column (length name) 1)))))) menu-bar) ;; Check the last menu item. (when (> column x-position)