commit 4df832750c811abc5ccbe7bfcefe1ad8f144af8e (HEAD, refs/remotes/origin/master) Author: Stefan Kangas Date: Fri Nov 1 23:56:12 2024 +0100 Don't start docstrings with "This function" * lisp/calculator.el (calculator-add-operators): * lisp/erc/erc-log.el (erc-generate-log-file-name-with-date) (erc-generate-log-file-name-short): * lisp/eshell/esh-mode.el (eshell-begin-on-new-line): * lisp/progmodes/hideif.el (hif-merge-ifdef-region): * lisp/tab-bar.el (tab-bar--event-to-item): * lisp/textmodes/artist.el (artist-no-rb-unset-point2) (artist-no-rb-unset-points): * lisp/which-key.el (which-key--hide-popup): Don't start function docstrings with "This function". diff --git a/lisp/calculator.el b/lisp/calculator.el index a9fe76259a8..0764a16370c 100644 --- a/lisp/calculator.el +++ b/lisp/calculator.el @@ -775,7 +775,7 @@ Defaults to 1." (or (nth 4 op) 1)) (defun calculator-add-operators (more-ops) - "This function handles operator addition. + "Handle operator addition. Adds MORE-OPS to `calculator-operator', called initially to handle `calculator-initial-operators' and `calculator-user-operators'." (let ((added-ops nil)) diff --git a/lisp/erc/erc-log.el b/lisp/erc/erc-log.el index 8311359ed09..a1102ebdcdf 100644 --- a/lisp/erc/erc-log.el +++ b/lisp/erc/erc-log.el @@ -360,13 +360,13 @@ The result is converted to lowercase, as IRC is case-insensitive." erc-log-channels-directory))))) (defun erc-generate-log-file-name-with-date (buffer &rest _ignore) - "This function computes a short log file name. + "Compute a short log file name with the current date. The name of the log file is composed of BUFFER and the current date. This function is a possible value for `erc-generate-log-file-name-function'." (concat (buffer-name buffer) "-" (format-time-string "%Y-%m-%d") ".txt")) (defun erc-generate-log-file-name-short (buffer &rest _ignore) - "This function computes a short log file name. + "Compute a short log file name. In fact, it only uses the buffer name of the BUFFER argument, so you can affect that using `rename-buffer' and the-like. This function is a possible value for diff --git a/lisp/eshell/esh-mode.el b/lisp/eshell/esh-mode.el index c86e3cc002c..4f94934fccd 100644 --- a/lisp/eshell/esh-mode.el +++ b/lisp/eshell/esh-mode.el @@ -537,7 +537,7 @@ Putting this function on `eshell-pre-command-hook' will mimic Plan 9's (eshell-interactive-output-filter nil string))) (defsubst eshell-begin-on-new-line () - "This function outputs a newline if not at beginning of line." + "Print a newline if not at beginning of line." (save-excursion (goto-char eshell-last-output-end) (or (bolp) diff --git a/lisp/progmodes/hideif.el b/lisp/progmodes/hideif.el index 9bcac0d8dc5..27a02e9805f 100644 --- a/lisp/progmodes/hideif.el +++ b/lisp/progmodes/hideif.el @@ -400,7 +400,7 @@ If there is a marked region from START to END it only shows the symbols within." (end-of-line 2))) (defun hif-merge-ifdef-region (start end) - "This function merges nearby ifdef regions to form a bigger overlay. + "Merge nearby ifdef regions to form a bigger overlay. The region is defined by START and END. This will decrease the number of overlays created." ;; Generally there is no need to call itself recursively since there should diff --git a/lisp/tab-bar.el b/lisp/tab-bar.el index 7fc04ab3c32..faf5df541e0 100644 --- a/lisp/tab-bar.el +++ b/lisp/tab-bar.el @@ -298,7 +298,7 @@ For any other value of KEY, the value is t." (defvar tab-bar--dragging-in-progress) (defun tab-bar--event-to-item (posn) - "This function extracts extra info from the mouse event at position POSN. + "Extract extra info from the mouse event at position POSN. It returns a list of the form (KEY KEY-BINDING CLOSE-P), where: KEY is a symbol representing a tab, such as \\='tab-1 or \\='current-tab; KEY-BINDING is the binding of KEY; diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el index c736f694083..eadf0988805 100644 --- a/lisp/textmodes/artist.el +++ b/lisp/textmodes/artist.el @@ -1997,7 +1997,7 @@ With optional argument SEE-THRU set to non-nil, text in the buffer (aset artist-rb-save-data 6 0))) (defun artist-no-rb-unset-point2 () - "This function unsets point 2 when not rubber-banding." + "Unset point 2 when not rubber-banding." (if (= (aref artist-rb-save-data 6) 1) (let ((x-now (artist-current-column)) (y-now (artist-current-line)) @@ -2020,7 +2020,7 @@ With optional argument SEE-THRU set to non-nil, text in the buffer (aset artist-rb-save-data 6 1))) (defun artist-no-rb-unset-points () - "This function unsets point 1 and 2 when not rubber-banding." + "Unset point 1 and 2 when not rubber-banding." (artist-no-rb-unset-point1) (artist-no-rb-unset-point2)) diff --git a/lisp/which-key.el b/lisp/which-key.el index 232145f7fb5..1da9a25090f 100644 --- a/lisp/which-key.el +++ b/lisp/which-key.el @@ -1219,7 +1219,7 @@ total height." ;;; Show/hide which-key buffer (defun which-key--hide-popup () - "This function is called to hide the which-key buffer." + "Hide the `which-key' buffer." (unless (or which-key-persistent-popup (member real-this-command which-key--paging-functions)) (setq which-key--last-try-2-loc nil) commit 471716c67d0d00a2e90dd7dfbc2bb88820a248a2 Author: Stefan Kangas Date: Fri Nov 1 22:54:11 2024 +0100 Mark unused reftex variable as obsolete * lisp/textmodes/reftex-vars.el (reftex-toc-split-windows-horizontally-fraction): Mark unused variable as obsolete in favor of 'reftex-toc-split-windows-fraction'. diff --git a/lisp/textmodes/reftex-vars.el b/lisp/textmodes/reftex-vars.el index 791b10412c9..aac735dc771 100644 --- a/lisp/textmodes/reftex-vars.el +++ b/lisp/textmodes/reftex-vars.el @@ -382,9 +382,6 @@ See also `reftex-toc-split-windows-horizontally'." :group 'reftex-table-of-contents-browser :type 'number) -(defvar reftex-toc-split-windows-horizontally-fraction 0.5 - "This variable is obsolete, use `reftex-toc-split-windows-fraction' instead.") - (defcustom reftex-toc-keep-other-windows t "Non-nil means, split the selected window to display the *toc* buffer. This helps to keep the window configuration, but makes the *toc* small. @@ -2112,6 +2109,9 @@ the following construct: \\bbb [xxx] {aaa}." :group 'reftex-miscellaneous-configurations :type 'hook) +(defvar reftex-toc-split-windows-horizontally-fraction 0.5) +(make-obsolete-variable 'reftex-toc-split-windows-horizontally-fraction + 'reftex-toc-split-windows-fraction "31.1") (provide 'reftex-vars) commit 673c906a5b7255987c09f534de45e555fc7fc9ae Author: Jim Porter Date: Fri Nov 1 10:40:25 2024 -0700 Improve evaluation of conditional Eshell forms This simplifies the logic for building these forms and also fixes an issue where a subcommand in a "&&" or "||" conditional had its output suppressed. * lisp/eshell/esh-cmd.el (eshell-structure-basic-command): Make obsolete. (eshell-silence-test-command): New function... (eshell-rewrite-while-command, eshell-rewrite-if-command): ... use it, and make the command form ourselves. (eshell-parse-pipeline): Use 'and' and 'or' to make the conditional command sequence. (eshell-command-success): New macro. (eshell-do-eval): Add support for 'and' and 'or' forms. * test/lisp/eshell/esh-cmd-tests.el (esh-cmd-test/and-operator/output) (esh-cmd-test/or-operator/output): New tests. diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index a8a19d2bcc9..2b1666a7293 100644 --- a/lisp/eshell/esh-cmd.el +++ b/lisp/eshell/esh-cmd.el @@ -556,6 +556,7 @@ implemented via rewriting, rather than as a function." The first of NAMES should be the positive form, and the second the negative. It's not likely that users should ever need to call this function." + (declare (obsolete nil "31.1")) (unless test (error "Missing test for `%s' command" keyword)) @@ -586,6 +587,12 @@ function." ;; Finally, create the form that represents this structured command. `(,func ,test ,@body)) +(defun eshell-silence-test-command (terms) + "If TERMS is a subcommand, wrap it in `eshell-commands' to silence output." + (if (memq (car-safe terms) '(eshell-as-subcommand eshell-lisp-command)) + `(eshell-command-success (eshell-commands ,terms t)) + terms)) + (defun eshell-rewrite-while-command (terms) "Rewrite a `while' command into its equivalent Eshell command form. Because the implementation of `while' relies upon conditional @@ -593,10 +600,13 @@ evaluation of its argument (i.e., use of a Lisp special form), it must be implemented via rewriting, rather than as a function." (when (and (stringp (car terms)) (member (car terms) '("while" "until"))) - (eshell-structure-basic-command - 'while '("while" "until") (car terms) - (cadr terms) - (caddr terms)))) + (unless (cadr terms) + (error "Missing test for `while' command")) + (let ((condition (eshell-silence-test-command (cadr terms)))) + (unless (string= (car terms) "while") + (setq condition `(not ,condition))) + `(while ,condition + ,(caddr terms))))) (defun eshell-rewrite-if-command (terms) "Rewrite an `if' command into its equivalent Eshell command form. @@ -605,18 +615,21 @@ evaluation of its argument (i.e., use of a Lisp special form), it must be implemented via rewriting, rather than as a function." (when (and (stringp (car terms)) (member (car terms) '("if" "unless"))) - (eshell-structure-basic-command - 'if '("if" "unless") (car terms) - (cadr terms) - (caddr terms) - (if (equal (nth 3 terms) "else") - ;; If there's an "else" keyword, allow chaining together - ;; multiple "if" forms... - (or (eshell-rewrite-if-command (nthcdr 4 terms)) - (nth 4 terms)) - ;; ... otherwise, only allow a single "else" block (without the - ;; keyword) as before for compatibility. - (nth 3 terms))))) + (unless (cadr terms) + (error "Missing test for `while' command")) + (let ((condition (eshell-silence-test-command (cadr terms))) + (then (caddr terms)) + (else (if (equal (nth 3 terms) "else") + ;; If there's an "else" keyword, allow chaining + ;; together multiple "if" forms... + (or (eshell-rewrite-if-command (nthcdr 4 terms)) + (nth 4 terms)) + ;; ... otherwise, only allow a single "else" block + ;; (without the keyword) as before for compatibility. + (nth 3 terms)))) + (unless (string= (car terms) "if") + (setq condition `(not ,condition))) + `(if ,condition ,then ,else)))) (defun eshell-set-exit-info (status &optional result) "Set the exit status and result for the last command. @@ -665,9 +678,10 @@ This means an exit code of 0." sep-terms (nreverse sep-terms)) (while results (cl-assert (car sep-terms)) - (setq final (eshell-structure-basic-command - 'if (string= (pop sep-terms) "&&") "if" - (pop results) final))) + (setq final `(,(if (string= (pop sep-terms) "&&") 'and 'or) + (eshell-command-success + (eshell-deferrable ,(pop results))) + ,final))) final)) (defun eshell-parse-subcommand-argument () @@ -751,12 +765,12 @@ if none)." ;; `eshell-do-eval' [Iterative evaluation]: ;; ;; @ Don't use special forms that conditionally evaluate their -;; arguments, such as `let*', unless Eshell explicitly supports -;; them. Eshell supports the following special forms: `catch', -;; `condition-case', `if', `let', `prog1', `progn', `quote', `setq', -;; `unwind-protect', and `while'. +;; arguments, such as `let*', unless Eshell explicitly supports them. +;; Eshell supports the following special forms: `and', `catch', +;; `condition-case', `if', `let', `or', `prog1', `progn', `quote', +;; `setq', `unwind-protect', and `while'. ;; -;; @ The two `special' variables are `eshell-current-handles' and +;; @ The two "special" variables are `eshell-current-handles' and ;; `eshell-current-subjob-p'. Bind them locally with a `let' if you ;; need to change them. Change them directly only if your intention ;; is to change the calling environment. @@ -803,6 +817,10 @@ returning it as (:eshell-background . PROCESSES)." (eshell-with-handles (,(not silent) 'append) ,object))) +(defmacro eshell-command-success (command) + "Return non-nil if COMMAND exits successfully." + `(progn ,command (eshell-exit-success-p))) + (defvar eshell-this-command-hook nil) (defmacro eshell-do-command (object) @@ -1182,6 +1200,18 @@ have been replaced by constants." (setcar form (car new-form)) (setcdr form (cdr new-form)))) (eshell-do-eval form synchronous-p)) + ((memq (car form) '(and or)) + (eshell-manipulate form (format-message "evaluating %s form" (car form)) + (let* ((result (eshell-do-eval (car args) synchronous-p)) + (value (cadr result))) + (if (or (null (cdr args)) + (if (eq (car form) 'or) value (not value))) + ;; If this is the last sub-form or we short-circuited, + ;; just return the result. + result + ;; Otherwise, remove this sub-form and re-evaluate. + (setcdr form (cdr args)) + (eshell-do-eval form synchronous-p))))) ((eq (car form) 'setcar) (setcar (cdr args) (eshell-do-eval (cadr args) synchronous-p)) (eval form)) diff --git a/test/lisp/eshell/esh-cmd-tests.el b/test/lisp/eshell/esh-cmd-tests.el index 0f388a9eba4..8b68013c60d 100644 --- a/test/lisp/eshell/esh-cmd-tests.el +++ b/test/lisp/eshell/esh-cmd-tests.el @@ -176,6 +176,21 @@ bug#59469." (eshell-match-command-output "[ foo = bar ] && echo hi" "\\`\\'"))) +(ert-deftest esh-cmd-test/and-operator/output () + "Test output with logical && operator." + (skip-unless (executable-find "sh")) + (with-temp-eshell + ;; Direct commands + (eshell-match-command-output "sh -c 'echo one; exit 1' && echo two" + "\\`one\n\\'") + (eshell-match-command-output "echo one && echo two" + "\\`one\ntwo\n\\'") + ;; Subcommands + (eshell-match-command-output "{ sh -c 'echo one; exit 1' } && echo two" + "\\`one\n\\'") + (eshell-match-command-output "{ echo one } && echo two" + "\\`one\ntwo\n\\'"))) + (ert-deftest esh-cmd-test/or-operator () "Test logical || operator." (skip-unless (executable-find "[")) @@ -185,6 +200,21 @@ bug#59469." (eshell-match-command-output "[ foo = bar ] || echo hi" "hi\n"))) +(ert-deftest esh-cmd-test/or-operator/output () + "Test output with logical || operator." + (skip-unless (executable-find "sh")) + (with-temp-eshell + ;; Direct commands + (eshell-match-command-output "sh -c 'echo one; exit 1' || echo two" + "\\`one\ntwo\n\\'") + (eshell-match-command-output "echo one || echo two" + "\\`one\n\\'") + ;; Subcommands + (eshell-match-command-output "{ sh -c 'echo one; exit 1' } || echo two" + "\\`one\ntwo\n\\'") + (eshell-match-command-output "{ echo one } || echo two" + "\\`one\n\\'"))) + ;; Pipelines commit ffda8dfe847094bd8488059be2f96270fe298fa5 Author: Stephen Gildea Date: Fri Nov 1 09:32:27 2024 -0700 ; time-stamp: Reformat some long doc strings for clarity. * lisp/time-stamp.el (time-stamp-format, time-stamp-pattern): Reformat doc strings for clarity. (group time-stamp): is a subgroup of "files", not "data". The "data" group seems to be for editing non-text files. * test/lisp/time-stamp-tests.el: Fix tense of some doc strings. diff --git a/lisp/time-stamp.el b/lisp/time-stamp.el index 8c28920d219..1b95396e744 100644 --- a/lisp/time-stamp.el +++ b/lisp/time-stamp.el @@ -5,8 +5,8 @@ ;; This file is part of GNU Emacs. -;; Maintainer: Stephen Gildea -;; Keywords: tools +;; Author: Stephen Gildea +;; Keywords: files, tools ;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by @@ -25,20 +25,19 @@ ;; A template in a file can be updated with a new time stamp when ;; you save the file. For example: -;; static char *ts = "sdmain.c Time-stamp: <2020-04-18 14:10:21 gildea>"; +;; static char *ts = "sdmain.c Time-stamp: <2024-04-18 14:10:21 gildea>"; ;; To use time-stamping, add this line to your init file: ;; (add-hook 'before-save-hook 'time-stamp) ;; Now any time-stamp templates in your files will be updated automatically. -;; See the documentation for the functions `time-stamp' -;; and `time-stamp-toggle-active' for details. +;; See the documentation for the function `time-stamp' for details. ;;; Code: (defgroup time-stamp nil "Maintain last change time stamps in files edited by Emacs." - :group 'data + :group 'files :group 'extensions) @@ -47,34 +46,34 @@ This is a string, used verbatim except for character sequences beginning with %, as follows. -%:A weekday name: `Monday' %#A gives uppercase: `MONDAY' -%3a abbreviated weekday: `Mon' %#a gives uppercase: `MON' -%:B month name: `January' %#B gives uppercase: `JANUARY' -%3b abbreviated month: `Jan' %#b gives uppercase: `JAN' -%02d day of month -%02H 24-hour clock hour -%02I 12-hour clock hour -%02m month number -%02M minute -%#p `am' or `pm' %P gives uppercase: `AM' or `PM' -%02S seconds -%w day number of week, Sunday is 0 -%02y 2-digit year %Y 4-digit year -%Z time zone name: `EST' %#Z gives lowercase: `est' -%5z time zone offset: `-0500' (since Emacs 27; see note below) +%:A weekday name: `Monday' %#A gives uppercase: `MONDAY' +%3a abbreviated weekday: `Mon' %#a gives uppercase: `MON' +%:B month name: `January' %#B gives uppercase: `JANUARY' +%3b abbreviated month: `Jan' %#b gives uppercase: `JAN' +%02d day of month +%02H 24-hour clock hour +%02I 12-hour clock hour +%02m month number +%02M minute +%#p `am' or `pm' %P gives uppercase: `AM' or `PM' +%02S seconds +%w day number of week, Sunday is 0 +%02y 2-digit year %Y 4-digit year +%Z time zone name: `EST' %#Z gives lowercase: `est' +%5z time zone offset: `-0500' (since Emacs 27; see note below) Non-date items: -%% a literal percent character: `%' -%f file name without directory %F absolute file name -%l login name %L full name of logged-in user -%q unqualified host name %Q fully-qualified host name -%h mail host name +%% a literal percent character: `%' +%f file name without directory %F absolute file name +%l login name %L full name of logged-in user +%q unqualified host name %Q fully-qualified host name +%h mail host name Decimal digits between the % and the type character specify the field width. Strings are truncated on the right. A leading zero in the field width zero-fills a number. -For example, to get the format used by the `date' command, +For example, to get a common format used by the `date' command, use \"%3a %3b %2d %02H:%02M:%02S %Z %Y\". The values of non-numeric formatted items depend on the locale @@ -266,20 +265,22 @@ If you were to change `time-stamp-pattern', `time-stamp-line-limit', `time-stamp-start', or `time-stamp-end' in your init file, you would be incompatible with other people's files. -See also `time-stamp-count' and `time-stamp-inserts-lines'. - Examples: -\"-10/\" (sets only `time-stamp-line-limit') +;; time-stamp-pattern: \"-10/\" + (sets only `time-stamp-line-limit') + +// time-stamp-pattern: \"-9/^Last modified: %%$\" + (sets `time-stamp-line-limit', `time-stamp-start' and `time-stamp-end') + +@c time-stamp-pattern: \"@set Time-stamp: %:B %1d, %Y$\" + (sets `time-stamp-start', `time-stamp-format' and `time-stamp-end') -\"-9/^Last modified: %%$\" (sets `time-stamp-line-limit', -`time-stamp-start' and `time-stamp-end') +%% time-stamp-pattern: \"newcommand{\\\\\\\\timestamp}{%%}\" + (sets `time-stamp-start'and `time-stamp-end') -\"@set Time-stamp: %:B %1d, %Y$\" (sets `time-stamp-start', -`time-stamp-format' and `time-stamp-end') -\"newcommand{\\\\\\\\timestamp}{%%}\" (sets `time-stamp-start' -and `time-stamp-end')") +See also `time-stamp-count' and `time-stamp-inserts-lines'.") ;;;###autoload(put 'time-stamp-pattern 'safe-local-variable 'stringp) @@ -287,8 +288,8 @@ and `time-stamp-end')") ;;;###autoload (defun time-stamp () "Update any time stamp string(s) in the buffer. -This function looks for a time stamp template and updates it with -the current date, time, and/or other info. +Look for a time stamp template and update it with the current date, +time, and/or other info. The template, which you manually create on one of the first 8 lines of the file before running this function, by default can look like @@ -297,7 +298,7 @@ one of the following (your choice): Time-stamp: \" \" This function writes the current time between the brackets or quotes, by default formatted like this: - Time-stamp: <2020-08-07 17:10:21 gildea> + Time-stamp: <2024-08-07 17:10:21 gildea> Although you can run this function manually to update a time stamp once, usually you want automatic time stamp updating. @@ -311,7 +312,7 @@ To enable automatic time-stamping for only a specific file, add this line to a local variables list near the end of the file: eval: (add-hook \\='before-save-hook \\='time-stamp nil t) -If the file has no time-stamp template, this function does nothing. +If the file has no time stamp template, this function does nothing. You can set `time-stamp-pattern' in a file's local variables list to customize the information in the time stamp and where it is written. @@ -419,7 +420,7 @@ Returns the end point, which is where `time-stamp' begins the next search." (cond ((not time-stamp-active) (if time-stamp-warn-inactive - ;; don't signal an error in a write-file-hook + ;; don't signal an error in a hook (progn (message "Warning: time-stamp-active is off; did not time-stamp buffer.") (sit-for 1)))) @@ -801,6 +802,8 @@ Suggests replacing OLD-FORM with NEW-FORM." ;; - The %_z format always outputs seconds, allowing all added padding ;; to be spaces. Without this rule, there would be no way to ;; request seconds that worked for both 2- and 3-digit hours. +;; (We consider 3-digit hours not because such offsets are in use but +;; instead to guide our design toward consistency and extensibility.) ;; - Conflicting options are rejected, lest users depend ;; on incidental behavior. ;; @@ -843,7 +846,7 @@ Suggests replacing OLD-FORM with NEW-FORM." colon-count field-width offset-secs) - "Formats a time offset according to a %z variation. + "Format a time offset according to a %z variation. With no flags, the output includes hours and minutes: +-HHMM unless there is a non-zero seconds part, in which case the seconds diff --git a/test/lisp/time-stamp-tests.el b/test/lisp/time-stamp-tests.el index a4c30d64225..36889257724 100644 --- a/test/lisp/time-stamp-tests.el +++ b/test/lisp/time-stamp-tests.el @@ -535,7 +535,7 @@ (should (equal (time-stamp-string "%#Z" ref-time1) utc-abbr))))) (ert-deftest time-stamp-format-time-zone-offset () - "Tests time-stamp legacy format %z and spot tests of new offset format %5z." + "Test time-stamp legacy format %z and spot-test new offset format %5z." (with-time-stamp-test-env (let ((utc-abbr (format-time-string "%#Z" ref-time1 t))) ;; documented 1995-2019, warned since 2019, will change @@ -617,7 +617,7 @@ (should (equal (time-stamp-string "No percent" ref-time1) "No percent")))) (ert-deftest time-stamp-format-multiple-conversions () - "Tests that multiple %-conversions are independent." + "Test that multiple %-conversions are independent." (with-time-stamp-test-env (let ((Mon (format-time-string "%a" ref-time1 t)) (MON (format-time-string "%^a" ref-time1 t)) @@ -719,7 +719,7 @@ ;;;; Setup for tests of time offset formatting with %z (defun formatz (format zone) - "Uses FORMAT to format the offset of ZONE, returning the result. + "Use FORMAT to format the offset of ZONE, returning the result. FORMAT must be time format \"%z\" or some variation thereof. ZONE is as the ZONE argument of the `format-time-string' function. This function is called by 99% of the `time-stamp' \"%z\" unit tests." @@ -733,7 +733,7 @@ This function is called by 99% of the `time-stamp' \"%z\" unit tests." ))) (defun format-time-offset (format offset-secs) - "Uses FORMAT to format the time zone represented by OFFSET-SECS. + "Use FORMAT to format the time zone represented by OFFSET-SECS. FORMAT must be time format \"%z\" or some variation thereof. This function is a wrapper around `time-stamp-formatz-from-parsed-options' and is called by some low-level `time-stamp' \"%z\" unit tests." @@ -765,20 +765,20 @@ and is called by some low-level `time-stamp' \"%z\" unit tests." trailing-string))) (defun fz-make+zone (h &optional m s) - "Creates a non-negative offset." + "Create a non-negative offset." (declare (pure t)) (let ((m (or m 0)) (s (or s 0))) (+ (* 3600 h) (* 60 m) s))) (defun fz-make-zone (h &optional m s) - "Creates a negative offset. The arguments are all non-negative." + "Create a negative offset. The arguments are all non-negative." (declare (pure t)) (- (fz-make+zone h m s))) (defmacro formatz-should-equal (zone expect) - "Formats ZONE and compares it to EXPECT. -Uses the free variables `form-string' and `pattern-mod'. + "Format ZONE and compares it to EXPECT. +Use the free variables `form-string' and `pattern-mod'. The functions in `pattern-mod' are composed left to right." (declare (debug t)) `(let ((result ,expect)) @@ -790,7 +790,7 @@ The functions in `pattern-mod' are composed left to right." ;; for hours, minutes, and seconds. (defun formatz-hours-exact-helper (form-string pattern-mod) - "Tests format %z with whole hours." + "Test format %z with whole hours." (formatz-should-equal (fz-make+zone 0) "+00") ;0 sign always +, both digits (formatz-should-equal (fz-make+zone 10) "+10") (formatz-should-equal (fz-make-zone 10) "-10") @@ -801,7 +801,7 @@ The functions in `pattern-mod' are composed left to right." ) (defun formatz-nonzero-minutes-helper (form-string pattern-mod) - "Tests format %z with whole minutes." + "Test format %z with whole minutes." (formatz-should-equal (fz-make+zone 0 30) "+00:30") ;has hours even though 0 (formatz-should-equal (fz-make-zone 0 30) "-00:30") (formatz-should-equal (fz-make+zone 0 4) "+00:04") @@ -819,7 +819,7 @@ The functions in `pattern-mod' are composed left to right." ) (defun formatz-nonzero-seconds-helper (form-string pattern-mod) - "Tests format %z with non-0 seconds." + "Test format %z with non-0 seconds." ;; non-0 seconds are always included (formatz-should-equal (fz-make+zone 0 0 50) "+00:00:50") (formatz-should-equal (fz-make-zone 0 0 50) "-00:00:50") @@ -848,7 +848,7 @@ The functions in `pattern-mod' are composed left to right." ) (defun formatz-hours-big-helper (form-string pattern-mod) - "Tests format %z with hours that don't fit in two digits." + "Test format %z with hours that don't fit in two digits." (formatz-should-equal (fz-make+zone 101) "+101:00") (formatz-should-equal (fz-make+zone 123 10) "+123:10") (formatz-should-equal (fz-make-zone 123 10) "-123:10") @@ -857,7 +857,7 @@ The functions in `pattern-mod' are composed left to right." ) (defun formatz-seconds-big-helper (form-string pattern-mod) - "Tests format %z with hours greater than 99 and non-zero seconds." + "Test format %z with hours greater than 99 and non-zero seconds." (formatz-should-equal (fz-make+zone 123 0 30) "+123:00:30") (formatz-should-equal (fz-make-zone 123 0 30) "-123:00:30") (formatz-should-equal (fz-make+zone 120 0 4) "+120:00:04") @@ -868,30 +868,30 @@ The functions in `pattern-mod' are composed left to right." ;; use the above test cases for multiple formats. (defun formatz-mod-del-colons (string) - "Returns STRING with any colons removed." + "Return STRING with any colons removed." (string-replace ":" "" string)) (defun formatz-mod-add-00 (string) - "Returns STRING with \"00\" appended." + "Return STRING with \"00\" appended." (concat string "00")) (defun formatz-mod-add-colon00 (string) - "Returns STRING with \":00\" appended." + "Return STRING with \":00\" appended." (concat string ":00")) (defun formatz-mod-pad-r10 (string) - "Returns STRING padded on the right to 10 characters." + "Return STRING padded on the right to 10 characters." (concat string (make-string (- 10 (length string)) ?\s))) (defun formatz-mod-pad-r12 (string) - "Returns STRING padded on the right to 12 characters." + "Return STRING padded on the right to 12 characters." (concat string (make-string (- 12 (length string)) ?\s))) ;; Convenience macro for generating groups of test cases. (defmacro formatz-generate-tests (form-strings hour-mod mins-mod secs-mod big-mod secbig-mod) - "Defines tests for time formats FORM-STRINGS. + "Define tests for time formats FORM-STRINGS. FORM-STRINGS is a list of formats, each \"%z\" or some variation thereof. Each of the remaining arguments is an unquoted list of the form @@ -925,7 +925,7 @@ the other expected results for hours greater than 99 with non-zero seconds." ert-test-list (list `(ert-deftest ,(intern (concat "formatz-" form-string "-hhmm")) () - ,(concat "Tests time-stamp format " form-string + ,(concat "Test time-stamp format " form-string " with whole hours or minutes.") (should (equal (formatz ,form-string (fz-make+zone 0)) ,(car hour-mod))) @@ -934,13 +934,13 @@ the other expected results for hours greater than 99 with non-zero seconds." ,(car mins-mod))) (formatz-nonzero-minutes-helper ,form-string ',(cdr mins-mod))) `(ert-deftest ,(intern (concat "formatz-" form-string "-seconds")) () - ,(concat "Tests time-stamp format " form-string + ,(concat "Test time-stamp format " form-string " with offsets that have non-zero seconds.") (should (equal (formatz ,form-string (fz-make+zone 0 0 30)) ,(car secs-mod))) (formatz-nonzero-seconds-helper ,form-string ',(cdr secs-mod))) `(ert-deftest ,(intern (concat "formatz-" form-string "-threedigit")) () - ,(concat "Tests time-stamp format " form-string + ,(concat "Test time-stamp format " form-string " with offsets that are 100 hours or greater.") (should (equal (formatz ,form-string (fz-make+zone 100)) ,(car big-mod))) @@ -981,7 +981,7 @@ the other expected results for hours greater than 99 with non-zero seconds." ;; The legacy exception for %z in time-stamp will need to remain ;; through at least 2024 and Emacs 28. (ert-deftest formatz-%z-spotcheck () - "Spot-checks internal implementation of time-stamp format %z." + "Spot-check internal implementation of time-stamp format %z." (should (equal (format-time-offset "%z" (fz-make+zone 0)) "+0000")) (should (equal (format-time-offset "%z" (fz-make+zone 0 30)) "+0030")) (should (equal (format-time-offset "%z" (fz-make+zone 0 0 30)) "+000030")) @@ -1104,7 +1104,7 @@ the other expected results for hours greater than 99 with non-zero seconds." ;;; Illegal %z formats (ert-deftest formatz-illegal-options () - "Tests that illegal/nonsensical/ambiguous %z formats don't produce output." + "Test that illegal/nonsensical/ambiguous %z formats don't produce output." ;; multiple options (should (equal "" (formatz "%_-z" 0))) (should (equal "" (formatz "%-_z" 0))) commit 872be2bb5febc5a720d6f4dbbd2fd30561385bb6 Author: Manuel Giraud Date: Wed Oct 30 17:24:24 2024 +0100 New `tmm-menubar' shortcut display style Bug#74111 * lisp/tmm.el (tmm-shortcut-inside-entry): New user option to control if the shortcut character is highlighted inside the menu entry's string. (tmm-add-one-shortcut): Compute the new shortcut style. (tmm-add-prompt, tmm-completion-prompt): Adapt the completion prompt according to the shortcut display style. (tmm-prompt): Adapt the prompt regexp. (tmm-shortcut): Simplify default case and make it work with this change. * etc/NEWS: Announce the option. diff --git a/etc/NEWS b/etc/NEWS index dceece0a8c0..4aba4b17055 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -592,6 +592,11 @@ instead. *** A new shortcut to navigate to previous menu. The hardcoded '^' shortcut gets you back to the previous menu. +--- +*** New user option 'tmm-shortcut-inside-entry'. +When non-nil, highlight the character shortcut in the menu entry's +string instead of preprending it and `tmm-mid-prompt' to said entry. + ** Foldout --- diff --git a/lisp/tmm.el b/lisp/tmm.el index 252c1e45afa..80991b246b6 100644 --- a/lisp/tmm.el +++ b/lisp/tmm.el @@ -83,11 +83,11 @@ or else the correct item might not be found in the `*Completions*' buffer." string)) (defcustom tmm-completion-prompt - "Press PageUp key to reach this buffer from the minibuffer. -Alternatively, you can use Up/Down keys (or your History keys) to change + "Press M-v/PageUp key to reach this buffer from the minibuffer. +Alternatively, You can use Up/Down keys (or your History keys) to change the item in the minibuffer, and press RET when you are done, or press -the marked letters to pick up your choice. Type ^ to go to the parent -menu. Type C-g or ESC ESC ESC to cancel. +the %s to pick up your choice. +Type ^ to go to the parent menu. Type C-g or ESC ESC ESC to cancel. " "Help text to insert on the top of the completion buffer. To save space, you can set this to nil, @@ -108,6 +108,13 @@ If you use only one of `downcase' or `upcase' for `tmm-shortcut-style', specify nil for this variable." :type '(choice integer (const nil))) +(defcustom tmm-shortcut-inside-entry nil + "Highlight the shortcut character in the menu entry's string. +When non-nil, the first menu-entry's character that acts as a shortcut +will be highlighted with the `highlight' face to help identifying it. +The `tmm-mid-prompt' string is not used then." + :type 'boolean) + (defface tmm-inactive '((t :inherit shadow)) "Face used for inactive menu items.") @@ -198,7 +205,8 @@ is used to go back through those sub-menus." (setq tail (cdr tail))))) (let ((prompt (concat "^" - (if (stringp tmm-mid-prompt) + (if (and (stringp tmm-mid-prompt) + (not tmm-shortcut-inside-entry)) (concat "." (regexp-quote tmm-mid-prompt)))))) (setq tmm--history @@ -283,7 +291,7 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'." (t (let* ((str (car elt)) (paren (string-search "(" str)) - (pos 0) (word 0) char) + (word 0) pos char) (catch 'done ; ??? is this slow? (while (and (or (not tmm-shortcut-words) ; no limit on words (< word tmm-shortcut-words)) ; try n words @@ -299,17 +307,34 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'." (if (not (memq char tmm-short-cuts)) (throw 'done char)))) (setq word (1+ word)) (setq pos (match-end 0))) + ;; A nil value for pos means that the shortcut is not inside the + ;; string of the menu entry. + (setq pos nil) (while (<= tmm-next-shortcut-digit ?9) ; no letter shortcut, pick a digit (setq char tmm-next-shortcut-digit) (setq tmm-next-shortcut-digit (1+ tmm-next-shortcut-digit)) (if (not (memq char tmm-short-cuts)) (throw 'done char))) (setq char nil)) (if char (setq tmm-short-cuts (cons char tmm-short-cuts))) - (cons (concat (if char (concat (char-to-string char) tmm-mid-prompt) - ;; keep them lined up in columns - (make-string (1+ (length tmm-mid-prompt)) ?\s)) - str) - (cdr elt)))))) + (cons + (if tmm-shortcut-inside-entry + (if char + (if pos + ;; A character inside the menu entry. + (let ((res (copy-sequence str))) + (aset res pos char) + (add-text-properties pos (1+ pos) '(face highlight) res) + res) + ;; A fallback digit character: place it in front of the + ;; menu entry. + (concat (propertize (char-to-string char) 'face 'highlight) + " " str)) + (make-string 2 ?\s)) + (concat (if char (concat (char-to-string char) tmm-mid-prompt) + ;; Keep them lined up in columns. + (make-string (1+ (length tmm-mid-prompt)) ?\s)) + str)) + (cdr elt)))))) ;; This returns the old map. (defun tmm-define-keys (minibuffer) @@ -328,7 +353,7 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'." (define-key map "\ev" 'tmm-goto-completions) (define-key map "\C-n" 'next-history-element) (define-key map "\C-p" 'previous-history-element) - ;; Previous menu shortcut (see `tmm-prompt') + ;; Previous menu shortcut (see `tmm-prompt'). (define-key map "^" 'self-insert-and-exit)) (prog1 (current-local-map) (use-local-map (append map (current-local-map)))))) @@ -384,7 +409,12 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'." (let ((inhibit-read-only t) (window (get-buffer-window "*Completions*"))) (goto-char (point-min)) - (insert tmm-completion-prompt) + (insert + (if tmm-shortcut-inside-entry + (format tmm-completion-prompt + (concat (propertize "highlighted" 'face 'highlight) " character")) + (format tmm-completion-prompt + (concat "character right before '" tmm-mid-prompt "' ")))) (when window ;; Try to show everything just inserted and preserve height of ;; *Completions* window. This should fix a behavior described @@ -406,13 +436,16 @@ Stores a list of all the shortcuts in the free variable `tmm-short-cuts'." (choose-completion)) ;; In minibuffer (delete-region (minibuffer-prompt-end) (point-max)) - (dolist (elt tmm-km-list) - (if (string= - (substring (car elt) 0 - (min (1+ (length tmm-mid-prompt)) - (length (car elt)))) - (concat (char-to-string c) tmm-mid-prompt)) - (setq s (car elt)))) + (dolist (elt tmm-km-list) + (let ((str (car elt)) + (index 0)) + (when tmm-shortcut-inside-entry + (if (get-char-property 0 'face str) + (setq index 0) + (let ((next (next-single-char-property-change 0 'face str))) + (setq index (if (= (length str) next) 0 next))))) + (if (= (aref str index) c) + (setq s str)))) (insert s) (exit-minibuffer))))) commit 1863028742977caf0d3f3973a94ef48eb040421b Author: Eli Zaretskii Date: Fri Nov 1 09:18:01 2024 +0200 Revert "Remove undefined variable from c-ts-common.el" This reverts commit 9ff155183ca560fc9005027a65c53544afb772a1. This problem was already fixed on the release branch m and the fix will merged soon. (Bug#74149) diff --git a/lisp/progmodes/c-ts-common.el b/lisp/progmodes/c-ts-common.el index cf55ddea8f7..5c7909ae858 100644 --- a/lisp/progmodes/c-ts-common.el +++ b/lisp/progmodes/c-ts-common.el @@ -336,7 +336,7 @@ and /* */ comments. SOFT works the same as in (delete-horizontal-space) (if soft (insert-and-inherit ?\n) - (newline 1))))) + (newline (if allow-auto-fill nil 1)))))) (cond ;; Line starts with //, or ///, or ////... ;; Or //! (used in rust).