commit 631f43d2bbe403e48d63d963281f1d948dee5263 (HEAD, refs/remotes/origin/master) Author: Stefan Kangas Date: Wed Jan 8 07:29:33 2025 +0100 ; Fix indentation in src/nsterm.h Reduce the diff between master and scratch/igc. diff --git a/src/nsterm.h b/src/nsterm.h index 1c86d6ea980..d03908eb521 100644 --- a/src/nsterm.h +++ b/src/nsterm.h @@ -704,26 +704,26 @@ enum ns_return_frame_mode ========================================================================== */ @interface EmacsScroller : NSScroller - { - struct window *window; - struct frame *frame; - NSResponder *prevResponder; +{ + struct window *window; + struct frame *frame; + NSResponder *prevResponder; - /* offset to the bottom of knob of last mouse down */ - CGFloat last_mouse_offset; - float min_portion; - int pixel_length; - enum scroll_bar_part last_hit_part; + /* offset to the bottom of knob of last mouse down */ + CGFloat last_mouse_offset; + float min_portion; + int pixel_length; + enum scroll_bar_part last_hit_part; - BOOL condemned; + BOOL condemned; - BOOL horizontal; + BOOL horizontal; - /* optimize against excessive positioning calls generated by emacs */ - int em_position; - int em_portion; - int em_whole; - } + /* optimize against excessive positioning calls generated by emacs */ + int em_position; + int em_portion; + int em_whole; +} - (void) mark; - (instancetype) initFrame: (NSRect )r window: (Lisp_Object)win; commit 2ec7396d5d190302c16b8d9bd7da14ac9381a21e Author: Stefan Kangas Date: Wed Jan 8 06:39:22 2025 +0100 Move define_error declaration and docstring * src/lisp.h (define_error): Move declaration to its proper place, make external, and move its docstring... * src/eval.c (define_error): ...to its function definition. diff --git a/src/eval.c b/src/eval.c index 3e899db4436..a73700419dd 100644 --- a/src/eval.c +++ b/src/eval.c @@ -1992,6 +1992,9 @@ signal_error (const char *s, Lisp_Object arg) xsignal (Qerror, Fcons (build_string (s), arg)); } +/* Simplified version of 'define-error' that works with pure + objects. */ + void define_error (Lisp_Object name, const char *message, Lisp_Object parent) { diff --git a/src/lisp.h b/src/lisp.h index 9da654cf9af..4217dd9e347 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -4867,6 +4867,7 @@ extern AVOID xsignal2 (Lisp_Object, Lisp_Object, Lisp_Object); extern AVOID xsignal3 (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object); extern AVOID signal_error (const char *, Lisp_Object); extern AVOID overflow_error (void); +extern void define_error (Lisp_Object name, const char *message, Lisp_Object parent); extern bool FUNCTIONP (Lisp_Object); extern Lisp_Object funcall_subr (struct Lisp_Subr *subr, ptrdiff_t numargs, Lisp_Object *arg_vector); extern Lisp_Object eval_sub (Lisp_Object form); @@ -5975,11 +5976,6 @@ maybe_gc (void) maybe_garbage_collect (); } -/* Simplified version of 'define-error' that works with pure - objects. */ -void -define_error (Lisp_Object name, const char *message, Lisp_Object parent); - INLINE_HEADER_END #endif /* EMACS_LISP_H */ commit 9811f80d252ae14dd655fce031fee5ffa95b689e Author: Stefan Kangas Date: Wed Jan 8 05:57:27 2025 +0100 ; Fix indentation diff --git a/src/lisp.h b/src/lisp.h index 339ff5e83b0..9da654cf9af 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1120,8 +1120,8 @@ SYMBOLP (Lisp_Object x) INLINE struct Lisp_Symbol_With_Pos * XSYMBOL_WITH_POS (Lisp_Object a) { - eassert (SYMBOL_WITH_POS_P (a)); - return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Symbol_With_Pos); + eassert (SYMBOL_WITH_POS_P (a)); + return XUNTAG (a, Lisp_Vectorlike, struct Lisp_Symbol_With_Pos); } INLINE Lisp_Object commit 601a1f1f2797488ea40292c27945fbfbe1bc3241 Author: F. Jason Park Date: Tue Jan 7 17:17:50 2025 -0800 ; Mark ERC keep-place-indicator test as :unstable * test/lisp/erc/erc-scenarios-keep-place-indicator.el (erc-scenarios-keep-place-indicator--follow): Don't run on EMBA pending investigation of test timing out. diff --git a/test/lisp/erc/erc-scenarios-keep-place-indicator.el b/test/lisp/erc/erc-scenarios-keep-place-indicator.el index 90bccf1b794..e89560ae772 100644 --- a/test/lisp/erc/erc-scenarios-keep-place-indicator.el +++ b/test/lisp/erc/erc-scenarios-keep-place-indicator.el @@ -31,6 +31,7 @@ ;; away, the indicator is updated if it's earlier in the buffer. (ert-deftest erc-scenarios-keep-place-indicator--follow () :tags `(:expensive-test + ,@(and (getenv "EMACS_EMBA_CI") '(:unstable)) ,@(and (getenv "ERC_TESTS_GRAPHICAL") '(:erc--graphical))) (when (version< emacs-version "29") (ert-skip "Times out")) ;; XXX verify that this continues to be the case ^. commit f9ecde75bbcd315557481585a1146f976f719504 Author: F. Jason Park Date: Sun Jan 5 15:59:46 2025 -0800 Improve use of Flyspell's API in erc-spelling * etc/ERC-NEWS: Announce deprecation of `erc-spelling-flyspell-verify' and `erc-spelling-unhighlight-word'. A slight behavioral change not worth mentioning is that, previously, ERC arranged for Flyspell to ignore any word immediately following a forward slash anywhere in the prompt input, even those for which the slash served as mere punctuation (a "stroke"), as in "something/misspelt." As of this change, Flyspell only unconditionally exempts an initial slash-prepended word, like "tableflip" in "ERC> /tableflip", and checks all others that follow against known slash commands. * lisp/erc/erc-spelling.el: Change top-level assignment of `erc-mode' symbol-property `flyspell-mode-predicate' from `erc-spelling-flyspell-verify' to `erc-spelling--flyspell-input-p'. (erc-spelling-mode, erc-spelling-disable): Remove local member from `flyspell-incorrect-hook'. (erc-spelling-init): Add `erc-spelling--flyspell-check' to `flyspell-incorrect-hook' locally. Don't bother explicitly setting `flyspell-generic-check-word-predicate' because Flyspell already does that for clients using the `flyspell-mode-predicte' interface. (erc-spelling-flyspell-verify, erc-spelling-unhighlight-word): Mark obsolete. (erc-spelling--flyspell-check, erc-spelling--flyspell-input-p): New functions, essentially the two halves of a reworked and bifurcated `erc-spelling-flyspell-verify'. Though used as a predicate, the first is not named as such because it performs side effects. * test/lisp/erc/erc-scenarios-spelling.el: New file. * test/lisp/erc/resources/spelling/auto-correct.eld: New file. (Bug#75327) diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS index f79d45b94b6..d491c3e5132 100644 --- a/etc/ERC-NEWS +++ b/etc/ERC-NEWS @@ -96,6 +96,11 @@ Although this has always been the case, string values are now more likely to be seen because ERC no longer coerces service names to port numbers. +*** The 'spelling' module makes better use of Flyspell's API. +As a consequence, the library functions 'erc-spelling-flyspell-verify' +and 'erc-spelling-unhighlight-word' are now unused and have been marked +obsolete. + * Changes in ERC 5.6 diff --git a/lisp/erc/erc-spelling.el b/lisp/erc/erc-spelling.el index 01e587af368..b354349bcec 100644 --- a/lisp/erc/erc-spelling.el +++ b/lisp/erc/erc-spelling.el @@ -48,6 +48,7 @@ (erc-spelling-init (current-buffer))))) ((remove-hook 'erc-connect-pre-hook #'erc-spelling-init) (dolist (buffer (erc-buffer-list)) + (remove-hook 'flyspell-incorrect-hook #'erc-spelling--flyspell-check t) (with-current-buffer buffer (flyspell-mode 0))))) (defcustom erc-spelling-dictionaries nil @@ -78,7 +79,7 @@ The current buffer is given by BUFFER." (if dicts (cadr (car dicts)) (erc-with-server-buffer ispell-local-dictionary))))) - (setq flyspell-generic-check-word-predicate #'erc-spelling-flyspell-verify) + (add-hook 'flyspell-incorrect-hook #'erc-spelling--flyspell-check 20 t) (flyspell-mode 1))) (defun erc-spelling-unhighlight-word (word) @@ -92,6 +93,7 @@ The cadr is the beginning and the caddr is the end." (defun erc-spelling-flyspell-verify () "Flyspell only the input line, nothing else." + (declare (obsolete erc-spelling--flyspell-input-p "31.1")) ;; FIXME: Don't use `flyspell-word'! (let ((word-data (and (boundp 'flyspell-word) flyspell-word))) @@ -109,9 +111,28 @@ The cadr is the beginning and the caddr is the end." nil) (t t))))) +;; Do this down here to avoid having to wrap the call sites above in +;; `with-suppressed-warnings'. +(make-obsolete 'erc-spelling-unhighlight-word + "value from `flyspell-get-word' now unused" "31.1") + +(defun erc-spelling--flyspell-check (beg end _) + "Return non-nil and remove overlay if text between BEG and END is correct." + (or (and erc-channel-users + (erc-get-channel-user (buffer-substring-no-properties beg end)) + (always (flyspell-unhighlight-at beg))) + (and erc-input-marker (> beg erc-input-marker) (eq (char-before beg) ?/) + (or (= beg (1+ erc-input-marker)) ; allow /misspelled at prompt + (erc-command-symbol (buffer-substring-no-properties beg end))) + (always (flyspell-unhighlight-at beg))))) + +(defun erc-spelling--flyspell-input-p () + "Return non-nil if Flyspell should check the prompt input at point." + (>= (point) erc-input-marker)) + (put 'erc-mode 'flyspell-mode-predicate - #'erc-spelling-flyspell-verify) + #'erc-spelling--flyspell-input-p) (provide 'erc-spelling) diff --git a/test/lisp/erc/erc-scenarios-spelling.el b/test/lisp/erc/erc-scenarios-spelling.el new file mode 100644 index 00000000000..a6660267fe8 --- /dev/null +++ b/test/lisp/erc/erc-scenarios-spelling.el @@ -0,0 +1,100 @@ +;;; erc-scenarios-spelling.el --- Basic spelling scenarios -*- lexical-binding: t -*- + +;; Copyright (C) 2025 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. + +;; 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 +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; 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 +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Code: + +(require 'ert-x) +(eval-and-compile + (let ((load-path (cons (ert-resource-directory) load-path))) + (require 'erc-scenarios-common))) + +(require 'erc-spelling) + +(ert-deftest erc-scenarios-spelling--auto-correct () + :tags `(:expensive-test + :unstable + ,@(and (getenv "ERC_TESTS_GRAPHICAL") '(:erc--graphical))) + + ;; Allow running locally with SELECTOR=t if user has ispell configured. + (unless (ignore-errors + (and (executable-find ispell-program-name) + (progn (ispell-check-version) t) + (member "american" (ispell-valid-dictionary-list)))) + (ert-skip "Missing ispell program")) + + (ert-with-temp-directory erc-scenarios-spelling + + (erc-scenarios-common-with-noninteractive-in-term + ((erc-scenarios-common-dialog "spelling") + (process-environment (cons + (format "HOME=%s" erc-scenarios-spelling) + process-environment)) + (dumb-server (erc-d-run "localhost" t 'auto-correct)) + (port (process-contact dumb-server :service)) + (expect (erc-d-t-make-expecter)) + (erc-autojoin-channels-alist '((foonet "#chan"))) + (erc-modules (cons 'spelling erc-modules)) + (erc-server-flood-penalty 0.1)) + + (ert-info ("Connect to foonet") + (with-current-buffer (erc :server "127.0.0.1" + :port port + :nick "tester" + :full-name "tester") + (funcall expect 10 "no longer marked as being") + (should erc-spelling-mode) + (should flyspell-mode))) + + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan")) + (should erc-spelling-mode) + (should flyspell-mode) + (funcall expect 10 " tester, welcome!") + + ;; Insert a command with one misspelled word. + (set-window-buffer nil (current-buffer)) + (execute-kbd-macro "\M->/AMSG an/dor /gmsg one fsbot two frob my shoe") + (funcall expect 10 "shoe") + + (let* ((ovs (overlays-in erc-input-marker (point))) + (ov1 (pop ovs)) + (ov2 (pop ovs))) + ;; At this point, flyspell should have done its thing. There + ;; should be two overlays: one on "dor" and the other on + ;; "frob". The spelling module's modifications should have + ;; prevented the two valid slash commands as well as "fsbot" + ;; from being highlighted. + (should-not ovs) + (should (flyspell-overlay-p ov1)) + (should (equal "dor" (buffer-substring (overlay-start ov1) + (overlay-end ov1)))) + (should (flyspell-overlay-p ov2)) + (should (equal "frob" (buffer-substring (overlay-start ov2) + (overlay-end ov2)))) + (goto-char (overlay-start ov2)) + + ;; Depending on the machine, this should become something + ;; like: "/AMSG an/dor /gmsg one fsbot two Rob my shoe". + (execute-kbd-macro (key-parse "M-TAB")) + (should (equal (overlays-in erc-input-marker (point-max)) + (list ov1))))) + + (when noninteractive + (erc-spelling-mode -1))))) + +;;; erc-scenarios-spelling.el ends here diff --git a/test/lisp/erc/resources/spelling/auto-correct.eld b/test/lisp/erc/resources/spelling/auto-correct.eld new file mode 100644 index 00000000000..0f00ee4825c --- /dev/null +++ b/test/lisp/erc/resources/spelling/auto-correct.eld @@ -0,0 +1,35 @@ +;; -*- mode: lisp-data; -*- +((nick 1 "NICK tester")) +((user 1 "USER user 0 * :tester") + (0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester") + (0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16") + (0 ":irc.foonet.org 003 tester :This server was created Wed, 05 May 2021 09:05:34 UTC") + (0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv") + (0 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server") + (0 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server") + (0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server") + (0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)") + (0 ":irc.foonet.org 252 tester 0 :IRC Operators online") + (0 ":irc.foonet.org 254 tester 1 :channels formed") + (0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers") + (0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3") + (0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3") + (0 ":irc.foonet.org 422 tester :MOTD File is missing")) + +((mode-user 10 "MODE tester +i") + (0 ":irc.foonet.org 221 tester +i") + (0 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.") + (0 ":irc.foonet.org 305 tester :You are no longer marked as being away")) + +((join 10 "JOIN #chan") + (0 ":tester!~u@247eaxkrufj44.irc JOIN #chan") + (0 ":irc.foonet.org 353 tester = #chan :alice fsbot @bob tester") + (0 ":irc.foonet.org 366 tester #chan :End of /NAMES list.")) + +((mode-chan 10 "MODE #chan") + (0 ":irc.foonet.org 324 tester #chan +nt") + (0 ":irc.foonet.org 329 tester #chan 1620205534") + (0 ":alice!~u@yppdd5tt4admc.irc PRIVMSG #chan :tester, welcome!") + (0 ":bob!~u@yppdd5tt4admc.irc PRIVMSG #chan :tester, welcome!") + (0 ":bob!~u@yppdd5tt4admc.irc PRIVMSG #chan :alice: Nor I no strength to climb without thy help.") + (0 ":alice!~u@yppdd5tt4admc.irc PRIVMSG #chan :bob: Nothing, but let him have thanks.")) commit c266c22b418541714889e85831de93c10a3c3fde Author: F. Jason Park Date: Sun Jan 5 16:58:50 2025 -0800 Fix regression in erc-nicks involving color pools * lisp/erc/erc-nicks.el (erc-nicks-colors): Tweak doc. (erc-nicks--create-pool-function): On graphic displays, set value to `erc-nicks--create-culled-pool', the original default. This fixes a bug in which ERC mapped all pool members to a primary color, thus excluding the bulk of them. Thanks to Trevor Arjeski for discovering it. (erc-nicks--create-coerced-pool): Mention the text-terminal-only requirement in doc. (erc-nicks-refresh): Improve doc. * test/lisp/erc/erc-nicks-tests.el (erc-nicks-tests--track-faces): Enable `erc-track-mode' prior to running body. diff --git a/lisp/erc/erc-nicks.el b/lisp/erc/erc-nicks.el index a2f1c6f4fa8..3429bcb33af 100644 --- a/lisp/erc/erc-nicks.el +++ b/lisp/erc/erc-nicks.el @@ -156,7 +156,7 @@ List of colors as strings (hex or named) or, alternatively, a single symbol representing a set of colors, like that produced by the function `defined-colors', which ERC associates with the symbol `defined'. Similarly, `all' tells ERC to use any 24-bit -color. To change the value mid-session, try +color. After updating this option's value mid-session, try \\[erc-nicks-refresh]." :type `(choice (const :tag "All 24-bit colors" all) (const :tag "Defined terminal colors" defined) @@ -382,16 +382,13 @@ Return a hex string." erc-nicks-color-adjustments (if (stringp color) (color-name-to-rgb color) color)))) -(defvar erc-nicks--create-pool-function #'erc-nicks--create-coerced-pool +(defvar erc-nicks--create-pool-function (if (display-graphic-p) + #'erc-nicks--create-culled-pool + #'erc-nicks--create-coerced-pool) "Filter function for initializing the pool of colors. Takes a list of adjustment functions, such as those named in -`erc-nicks-color-adjustments', and a list of colors. Returns -another list whose members need not be among the original -candidates. Users should note that this variable, along with its -predefined function values, `erc-nicks--create-coerced-pool' and -`erc-nicks--create-culled-pool', can be made public in a future -version of this module, perhaps as a single user option, given -sufficient demand.") +`erc-nicks-color-adjustments', and a list of colors. Returns another +list whose members need not be among the original candidates.") (defun erc-nicks--create-coerced-pool (adjustments colors) "Return COLORS that fall within parameters heeded by ADJUSTMENTS. @@ -401,7 +398,8 @@ That is, accept the nearest initially found as \"close enough,\" knowing that values may fall outside desired parameters and thus yield a larger pool than simple culling might produce. When debugging, add candidates to `erc-nicks--colors-rejects' that map -to the same output color as some prior candidate." +to the same output color as some prior candidate. Only effective +on non-graphical displays." (let* ((seen (make-hash-table :test #'equal)) (erc-nicks-color-adjustments adjustments) pool) @@ -675,10 +673,10 @@ Abandon search after examining LIMIT faces." (defun erc-nicks-refresh (debug) "Recompute faces for all nicks on current network. -With DEBUG, review affected faces or colors. Exactly which of -the two depends on the value of `erc-nicks-colors'. Note that -the list of rejected faces may include duplicates of accepted -ones." +With DEBUG (\\[universal-argument]), review affected faces or colors, +exactly which depends on the value of `erc-nicks-colors'. Expect users +to know that the list of rejected faces may include candidates that are +effectively duplicates because they map to already admitted ones." (interactive "P") (unless (derived-mode-p 'erc-mode) (user-error "Not an ERC buffer")) diff --git a/test/lisp/erc/erc-nicks-tests.el b/test/lisp/erc/erc-nicks-tests.el index 1e9808d1bed..a6d2f6034d4 100644 --- a/test/lisp/erc/erc-nicks-tests.el +++ b/test/lisp/erc/erc-nicks-tests.el @@ -579,6 +579,7 @@ (defvar erc-track--normal-faces) (erc-tests-common-make-server-buf) + (erc-track-mode +1) (erc-nicks-mode +1) (let ((erc-modules (cons 'nicks erc-modules)) commit 8d687695c528e4edb04cca5602470d349e333258 Author: Arash Esbati Date: Tue Jan 7 22:02:13 2025 +0100 Update RefTeX manual * doc/misc/reftex.texi: (Builtin Label Environments): Mention supported LaTeX packages ctable, minted and listings. (Reference Styles): Update the supported reference styles and the corresponding macros. (Citation Styles): Mention support for biblatex package. (Language Support): Describe usage of non-ASCII characters in the LaTeX \label definition. (Style Files): Mention biblatex.el as well. (Options - Defining Label Environments): Add entry for `reftex-label-regexps' option. Other minor improvements. diff --git a/doc/misc/reftex.texi b/doc/misc/reftex.texi index 20e9b15e94e..5973140734f 100644 --- a/doc/misc/reftex.texi +++ b/doc/misc/reftex.texi @@ -259,8 +259,8 @@ To turn @RefTeX{} Mode on and off in a particular buffer, use LaTeX files, add the following lines to your @file{.emacs} file: @example -(add-hook 'LaTeX-mode-hook 'turn-on-reftex) ; with AUCTeX LaTeX mode -(add-hook 'latex-mode-hook 'turn-on-reftex) ; with Emacs latex mode +(add-hook 'LaTeX-mode-hook #'turn-on-reftex) ; with AUCTeX LaTeX mode +(add-hook 'latex-mode-hook #'turn-on-reftex) ; with Emacs latex mode @end example That's all! @@ -333,11 +333,11 @@ Which labels are created how is configurable with the variable @code{reftex-insert-label-flags}. @item -@b{Referencing Labels}@* To make a reference, type @kbd{C-c )} -(@code{reftex-reference}). This shows an outline of the document with -all labels of a certain type (figure, equation,...) and some label -context. Selecting a label inserts a @code{\ref@{@var{label}@}} macro -into the original buffer. +@b{Referencing Labels}@* +To make a reference, type @kbd{C-c )} (@code{reftex-reference}). This +shows an outline of the document with all labels of a certain type +(figure, equation,...) and some label context. Selecting a label +inserts a @code{\ref@{@var{label}@}} macro into the original buffer. @end itemize @item @@ -352,12 +352,11 @@ different macros). @item @b{Index Support}@* -@RefTeX{} helps to enter index entries. It also compiles all -entries into an alphabetically sorted @file{*Index*} buffer which you -can use to check and edit the entries. @RefTeX{} knows about the -standard index macros and can be configured to recognize any additional -macros you have defined (@code{reftex-index-macros}). Multiple indices -are supported. +@RefTeX{} helps to enter index entries. It also compiles all entries +into an alphabetically sorted @file{*Index*} buffer which you can use to +check and edit the entries. @RefTeX{} knows about the standard index +macros and can be configured to recognize any additional macros you have +defined (@code{reftex-index-macros}). Multiple indices are supported. @itemize @bullet @item @@ -383,7 +382,8 @@ all entries. @end itemize @page -@item @b{Viewing Cross-References}@* +@item +@b{Viewing Cross-References}@* When point is on the @var{key} argument of a cross-referencing macro (@code{\label}, @code{\ref}, @code{\cite}, @code{\bibitem}, @code{\index}, and variations) or inside a @BibTeX{} database entry, you @@ -403,20 +403,21 @@ all parts of the document, and across document borders (@file{xr.sty}). @item -@b{Document Parsing}@* @RefTeX{} needs to parse the document in -order to find labels and other information. It does it automatically -once and updates its list internally when @code{reftex-label} and -@code{reftex-index} are used. To enforce reparsing, call any of the -commands described above with a raw @kbd{C-u} prefix, or press the -@kbd{r} key in the label selection buffer, the table of contents -buffer, or the index buffer. +@b{Document Parsing}@* +@RefTeX{} needs to parse the document in order to find labels and other +information. It does it automatically once and updates its list +internally when @code{reftex-label} and @code{reftex-index} are used. +To enforce reparsing, call any of the commands described above with a +raw @kbd{C-u} prefix, or press the @kbd{r} key in the label selection +buffer, the table of contents buffer, or the index buffer. @item -@b{@AUCTeX{}} @* If your major @LaTeX{} mode is @AUCTeX{}, @RefTeX{} can -cooperate with it (see variable @code{reftex-plug-into-AUCTeX}). @AUCTeX{} -contains style files which trigger appropriate settings in -@RefTeX{}, so that for many of the popular @LaTeX{} packages no -additional customizations will be necessary. +@b{@AUCTeX{}}@* +If your major @LaTeX{} mode is @AUCTeX{}, @RefTeX{} can cooperate with +it (see variable @code{reftex-plug-into-AUCTeX}). @AUCTeX{} contains +style files which trigger appropriate settings in @RefTeX{}, so that for +many of the popular @LaTeX{} packages no additional customizations will +be necessary. @item @b{Useful Settings}@* @@ -438,13 +439,14 @@ If you have a large number of macros defined, you may want to write an @AUCTeX{} style file to support them with both @AUCTeX{} and @RefTeX{}. -@item @b{Where Next?}@* Go ahead and use @RefTeX{}. Use its menus -until you have picked up the key bindings. For an overview of what you -can do in each of the different special buffers, press @kbd{?}. Read -the manual if you get stuck, or if you are curious what else might be -available. The first part of the manual explains in -a tutorial way how to use and customize @RefTeX{}. The second -part is a command and variable reference. +@item +@b{Where Next?}@* +Go ahead and use @RefTeX{}. Use its menus until you have picked up the +key bindings. For an overview of what you can do in each of the +different special buffers, press @kbd{?}. Read the manual if you get +stuck, or if you are curious what else might be available. The first +part of the manual explains in a tutorial way how to use and customize +@RefTeX{}. The second part is a command and variable reference. @end enumerate @node Table of Contents @@ -1066,21 +1068,36 @@ the @LaTeX{} core stuff) @code{alignat}, @code{xalignat}, @code{xxalignat}, @code{subequations} (from AMS-@LaTeX{}'s @file{amsmath.sty} package) @item -@cindex @code{endnote}, LaTeX package -@cindex LaTeX packages, @code{endnote} -@cindex @code{\endnote}, LaTeX macro -the @code{\endnote} macro (from @file{endnotes.sty}) -@item @cindex @code{fancybox}, LaTeX package @cindex LaTeX packages, @code{fancybox} @cindex @code{Beqnarray}, LaTeX environment @code{Beqnarray} (@file{fancybox.sty}) @item +@cindex @code{ctable}, LaTeX package +@cindex LaTeX packages, @code{ctable} +@cindex @code{\ctable}, LaTeX macro +the @code{\ctable} macro (from @file{ctable.sty}) +@item +@cindex @code{endnote}, LaTeX package +@cindex LaTeX packages, @code{endnote} +@cindex @code{\endnote}, LaTeX macro +the @code{\endnote} macro (from @file{endnotes.sty}) +@item @cindex @code{floatfig}, LaTeX package @cindex LaTeX packages, @code{floatfig} @cindex @code{floatingfig}, LaTeX environment @code{floatingfig} (@file{floatfig.sty}) @item +@cindex @code{minted}, LaTeX package +@cindex LaTeX packages, @code{minted} +@cindex @code{listing}, LaTeX environment +@code{listing} (@file{minted.sty}) +@item +@cindex @code{listings}, LaTeX package +@cindex LaTeX packages, @code{listings} +@cindex @code{lstlisting}, LaTeX environment +@code{lstlisting} (@file{listings.sty}) +@item @cindex @code{longtable}, LaTeX package @cindex LaTeX packages, @code{longtable} @cindex @code{longtable}, LaTeX environment @@ -1104,7 +1121,7 @@ the @code{\endnote} macro (from @file{endnotes.sty}) @cindex @code{sidewaystable}, LaTeX environment @code{sidewaysfigure}, @code{sidewaystable} (@file{rotating.sty}) @item -@cindex @code{subfig}, LaTeX package +@cindex @code{subfigure}, LaTeX package @cindex LaTeX packages, @code{subfigure} @cindex @code{subfigure}, LaTeX environment @cindex @code{subfigure*}, LaTeX environment @@ -1210,10 +1227,10 @@ automatically create labels for the new environments. @lisp (add-hook 'LaTeX-mode-hook - (lambda () - (LaTeX-add-environments - '("axiom" LaTeX-env-label) - '("theorem" LaTeX-env-label)))) + (lambda () + (LaTeX-add-environments + '("axiom" LaTeX-env-label) + '("theorem" LaTeX-env-label)))) @end lisp @@ -1599,12 +1616,15 @@ convenient way. @RefTeX{} comes equipped with a set of so-called reference styles where each relates to one or more reference macros. The standard macros -@samp{\ref} and @samp{\pageref} or provided by the ``Default'' style. -The ``Varioref'' style offers macros for the @samp{varioref} @LaTeX{} -package (@samp{\vref}, @samp{\Vref}, @samp{\Ref}, @samp{\vpageref}), -``Fancyref'' for the @samp{fancyref} package (@samp{\fref}, -@samp{\Fref}) and ``Hyperref'' for the @samp{hyperref} package -(@samp{\autoref}, @samp{\autopageref}). +@samp{\ref}, @samp{\Ref}, @samp{\footref} and @samp{\pageref} are +provided by the ``Default'' style. The ``Varioref'' style offers macros +for the @samp{varioref} @LaTeX{} package (@samp{\vref}, @samp{\Vref}, +and @samp{\vpageref}), ``Fancyref'' for the @samp{fancyref} package +(@samp{\fref}, @samp{\Fref}), ``Hyperref'' for the @samp{hyperref} +package (@samp{\autoref}, @samp{\autopageref}), ``Cleveref'' for the +@samp{cleveref} package (@samp{\cref}, @samp{\Cref}, @samp{\cpageref} +and @samp{\Cpageref}) and ``AMSmath'' for the @samp{amsmath} package +(@samp{\eqref}). @vindex reftex-ref-style-default-list A style can be toggled by selecting the respective entry in the @@ -1885,11 +1905,13 @@ buffers by adding the following expression to your init file: @node Citation Styles @section Citation Styles @cindex Citation styles +@cindex Citation styles, @code{biblatex} @cindex Citation styles, @code{natbib} @cindex Citation styles, @code{harvard} @cindex Citation styles, @code{chicago} @cindex Citation styles, @code{jurabib} @cindex Citation styles, @ConTeXt{} +@cindex @code{biblatex}, citation style @cindex @code{natbib}, citation style @cindex @code{harvard}, citation style @cindex @code{chicago}, citation style @@ -1903,12 +1925,12 @@ citations as used in many natural sciences, a variety of packages has been developed which define derived forms of the @code{\cite} macro. @RefTeX{} can be configured to produce these citation macros as well by setting the variable @code{reftex-cite-format}. For the most commonly -used @LaTeX{} packages (@code{natbib}, @code{harvard}, @code{chicago}, -@code{jurabib}) and for @ConTeXt{} this may be done from the menu, under -@code{Ref->Citation Styles}. Since there are usually several macros to -create the citations, executing @code{reftex-citation} (@kbd{C-c [}) -starts by prompting for the correct macro. For the Natbib style, this -looks like this: +used @LaTeX{} packages (@code{biblatex}, @code{natbib}, @code{harvard}, +@code{chicago}, @code{jurabib}) and for @ConTeXt{} this may be done from +the menu, under @code{Ref->Citation Styles}. Since there are usually +several macros to create the citations, executing @code{reftex-citation} +(@kbd{C-c [}) starts by prompting for the correct macro. For the Natbib +style, this looks like this: @example SELECT A CITATION FORMAT @@ -1925,6 +1947,31 @@ SELECT A CITATION FORMAT [y] \citeyear@{%l@} @end example +@noindent +And for the Biblatex style, it looks like this: + +@example +SELECT A CITATION FORMAT + +[^M] \cite[][]@{%l@} +[C] \cite*[][]@{%l@} +[t] \textcite[][]@{%l@} +[T] \textcite*[][]@{%l@} +[p] \parencite[][]@{%l@} +[P] \parencite*[][]@{%l@} +[f] \footcite[][]@{%l@} +[s] \smartcite[][]@{%l@} +[u] \autocite[][]@{%l@} +[U] \autocite*[][]@{%l@} +[a] \citeauthor@{%l@} +[A] \citeauthor*@{%l@} +[i] \citetitle@{%l@} +[I] \citetitle*@{%l@} +[y] \citeyear@{%l@} +[Y] \citeyear*@{%l@} +[n] \nocite@{%l@} +@end example + @vindex reftex-cite-prompt-optional-args If citation formats contain empty pairs of square brackets, @RefTeX{} will prompt for values of these optional arguments if you call the @@ -1942,6 +1989,13 @@ To make one of these styles the default, customize the variable (setq reftex-cite-format 'natbib) @end lisp +@noindent +Or this if you prefer the biblatex package: + +@lisp +(setq reftex-cite-format 'biblatex) +@end lisp + You can also use @AUCTeX{} style files to automatically set the citation style based on the @code{usepackage} commands in a given document. @xref{Style Files}, for information on how to set up the style @@ -2909,23 +2963,28 @@ settings work well for English. If you are writing in a different language, the following hints may be useful: @itemize @bullet -@item @vindex reftex-derive-label-parameters @vindex reftex-abbrev-parameters +@item The mechanism to derive a label from context includes the abbreviation of words and omission of unimportant words. These mechanisms may have to be changed for other languages. See the variables @code{reftex-derive-label-parameters} and @code{reftex-abbrev-parameters}. -@item @vindex reftex-translate-to-ascii-function @vindex reftex-label-illegal-re -Also, when a label is derived from context, @RefTeX{} clears the -context string from non-ASCII characters in order to make a valid label. -If there should ever be a version of @TeX{} which allows extended -characters @emph{in labels}, then we will have to look at the -variables @code{reftex-translate-to-ascii-function} and -@code{reftex-label-illegal-re}. +@item +Also, when a label is derived from context, @RefTeX{} clears the context +string from non-ASCII characters in order to make a label. Starting +with @LaTeX{} release 2019-10-01, non-ASCII characters are allowed in +@LaTeX{}'s @code{\label}/@code{\ref} mechanism. If you want to change +@RefTeX{}'s behavior and allow extended characters in labels, then take +a look at the variables @code{reftex-translate-to-ascii-function} and +@code{reftex-label-illegal-re}. The following example allows any +letters and digits (among other characters) in the label definition: +@lisp +(setq reftex-label-illegal-re "[^-[:alnum:]_+=:;,.]") +@end lisp @item When a label is referenced, @RefTeX{} looks at the word before point @@ -3025,7 +3084,7 @@ the new extension must also be known to @AUCTeX{} via the variable (setq reftex-file-extensions '(("nw" "tex" ".tex" ".ltx") ("bib" ".bib"))) (setq TeX-file-extensions - '( "nw" "tex" "sty" "cls" "ltx" "texi" "texinfo")) + '("nw" "tex" "sty" "cls" "ltx" "texi" "texinfo")) @end lisp @node Optimizations @@ -3289,11 +3348,11 @@ Labels}). Style files are Emacs Lisp files which are evaluated by @AUCTeX{} in association with the @code{\documentclass} and @code{\usepackage} commands of a document (@pxref{Style Files,,,auctex}). Support for -@RefTeX{} in such a style file is useful when the @LaTeX{} style -defines macros or environments connected with labels, citations, or the -index. Many style files (e.g., @file{amsmath.el} or @file{natbib.el}) -distributed with @AUCTeX{} already support @RefTeX{} in this -way. +@RefTeX{} in such a style file is useful when the @LaTeX{} style defines +macros or environments connected with labels, citations, or the index. +Many style files (e.g., @file{amsmath.el}, @file{natbib.el} or +@file{biblatex.el}) distributed with @AUCTeX{} already support @RefTeX{} +in this way. Before calling a @RefTeX{} function, the style hook should always test for the availability of the function, so that the style file will @@ -4127,6 +4186,23 @@ spliced into the list. However, builtin defaults should normally be set with the variable @code{reftex-default-label-alist-entries}. @end defopt +@defopt reftex-label-regexps +List of regular expressions matching @samp{\label} definitions. The +default value matches usual @samp{\label@{@dots{}@}} definitions and key +value style @samp{[@dots{}, label = @{@dots{}@}, @dots{}]} label +definitions. The regular expression for key value style explicitly +looks for environments provided by the packages @code{listings} +(@code{lstlisting}), @code{beamer} (@code{frame}), @code{breqn} +(@code{dmath}, @code{dseries}, @code{dgroup}, @code{darray}) and the +macro @code{\ctable} provided by the package of the same name. + +It is assumed that the regexp group 1 matches the label text, so you +have to define it using @samp{\(?1:...\)} when adding new regexps. + +When changed from Lisp, make sure to call +@code{reftex-compile-variables} afterwards to make the change effective. +@end defopt + @defopt reftex-section-prefixes Prefixes for section labels. When the label prefix given in an entry in @code{reftex-label-alist} contains @samp{%S}, this list is used to commit 1ef7deb2f723f9129135e8676366d79eee83e870 Author: Roland Winkler Date: Tue Jan 7 11:56:48 2025 -0600 bibtex-braced-string-syntax-table: fix bug #68477 * lisp/textmodes/bibtex.el (bibtex-braced-string-syntax-table): Give all parentheses the syntax punctuation so that we do not choke because of unbalanced parentheses other than braces (bug diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el index 0ea72e3abe9..a8f803f7313 100644 --- a/lisp/textmodes/bibtex.el +++ b/lisp/textmodes/bibtex.el @@ -1880,12 +1880,15 @@ BibTeX field as necessary." (defconst bibtex-braced-string-syntax-table (let ((st (make-syntax-table))) + ;; Give all parentheses the syntax punctuation so that we do not choke + ;; because of unbalanced parentheses other than braces (bug #68477). + (map-char-table + (lambda (key value) + (if (memq (car value) '(4 5)) ; 4 = open parenthesis, 5 = close + (modify-syntax-entry key "." st))) + st) (modify-syntax-entry ?\{ "(}" st) (modify-syntax-entry ?\} "){" st) - (modify-syntax-entry ?\[ "." st) - (modify-syntax-entry ?\] "." st) - (modify-syntax-entry ?\( "." st) - (modify-syntax-entry ?\) "." st) (modify-syntax-entry ?\\ "." st) (modify-syntax-entry ?\" "." st) st) commit 4bf0f6655142b9e216325d051943b7b7ca4d2cd7 Author: Juri Linkov Date: Tue Jan 7 20:44:09 2025 +0200 Prefer `%s` format over `%S` for buffers This restores the `%s` format` for buffers after fba3c7ff3f68f05d32541440e0a22ec667c0ad66. * lisp/gnus/nnimap.el (nnimap-make-process-buffer): * lisp/gnus/nntp.el (nntp-make-process-buffer): * lisp/simple.el (next-error-internal): Prefer more user-readable `%s` format over `%S` for buffers. diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el index b9c6586c03f..f63138300b1 100644 --- a/lisp/gnus/nnimap.el +++ b/lisp/gnus/nnimap.el @@ -386,7 +386,7 @@ during splitting, which may be slow." (defun nnimap-make-process-buffer (buffer) (with-current-buffer - (generate-new-buffer (format " *nnimap %s %s %S*" + (generate-new-buffer (format " *nnimap %s %s %s*" nnimap-address nnimap-server-port buffer)) (mm-disable-multibyte) diff --git a/lisp/gnus/nntp.el b/lisp/gnus/nntp.el index aaa80e035ea..a086421b049 100644 --- a/lisp/gnus/nntp.el +++ b/lisp/gnus/nntp.el @@ -1189,7 +1189,7 @@ If SEND-IF-FORCE, only send authinfo to the server if the "Create a new, fresh buffer usable for nntp process connections." (with-current-buffer (generate-new-buffer - (format " *server %s %s %S*" + (format " *server %s %s %s*" nntp-address nntp-port-number buffer)) (gnus-add-buffer) (mm-disable-multibyte) diff --git a/lisp/simple.el b/lisp/simple.el index b0490bb36d4..c47ea8660f9 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -393,7 +393,7 @@ To control which errors are matched, customize the variable (next-error-found buffer (current-buffer)) (when (or next-error-verbose (not (eq prev next-error-last-buffer))) - (message "Current locus from %S" next-error-last-buffer))))) + (message "Current locus from %s" next-error-last-buffer))))) (defun next-error-quit-window (from-buffer to-buffer) "Quit window of FROM-BUFFER when the prefix arg is 0. commit d5c3173366354b94dc9a421caaf8b66015038998 Author: Juri Linkov Date: Tue Jan 7 20:22:14 2025 +0200 Move calendar-month metadata to calendar-read-date (bug#68214) * lisp/minibuffer.el (completion-category-defaults): Move the 'calendar-month' default value to the metadata in calendar-read-date. * lisp/calendar/calendar.el (calendar-read-date): Add display-sort-function moved from completion-category-defaults. diff --git a/lisp/calendar/calendar.el b/lisp/calendar/calendar.el index acacaf345dc..75a942c6030 100644 --- a/lisp/calendar/calendar.el +++ b/lisp/calendar/calendar.el @@ -2354,7 +2354,8 @@ returned is (month year)." (completion-table-with-metadata (completion-table-case-fold (append month-array nil)) - `((category . calendar-month))) + `((category . calendar-month) + (display-sort-function . identity))) nil t nil nil defmon) (calendar-make-alist month-array 1) t))) (defday (calendar-extract-day default-date)) diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index abf55164995..1f33bda5f65 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -1197,8 +1197,7 @@ styles for specific categories, such as files, buffers, etc." (project-file (styles . (substring))) (xref-location (styles . (substring))) (info-menu (styles . (basic substring))) - (symbol-help (styles . (basic shorthand substring))) - (calendar-month (display-sort-function . identity))) + (symbol-help (styles . (basic shorthand substring)))) "Default settings for specific completion categories. Each entry has the shape (CATEGORY . ALIST) where ALIST is commit e41a7d8127423307018f369e8739319f1de9b3fa Author: Stefan Kangas Date: Tue Jan 7 08:15:41 2025 +0100 Improve docstring of image-dired-show-all-from-dir * lisp/image/image-dired.el (image-dired-show-all-from-dir): Improve docstring. diff --git a/etc/NEWS b/etc/NEWS index 00e9e1871cd..37e5669b139 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -318,6 +318,12 @@ modal editing packages. ** Smerge *** New command 'smerge-extend' extends a conflict over surrounding lines. +** Image Dired + +*** 'image-dired-show-all-from-dir' takes the same first argument as 'dired'. +This allows passing a string with wildcards, or a cons cell where the +first element is a list and the rest is a list of files. + ** Browse URL *** New user option 'browse-url-transform-alist'. diff --git a/lisp/image/image-dired.el b/lisp/image/image-dired.el index de548c6c729..452be29c5d5 100644 --- a/lisp/image/image-dired.el +++ b/lisp/image/image-dired.el @@ -618,17 +618,22 @@ thumbnail buffer to be selected." (image-dired--update-header-line)))) ;;;###autoload -(defun image-dired-show-all-from-dir (dir) - "Make a thumbnail buffer for all images in DIR and display it. -Any file matching `image-dired--file-name-regexp' is considered an -image file. +(defun image-dired-show-all-from-dir (dirname) + "Make a thumbnail buffer for all images in DIRNAME and display it. + +The DIRNAME argument is passed along to `dired', and can therefore be +either a string with wildcards or a cons, as described in the +documentation for that function. Refer to it for more details. If the number of image files in DIR exceeds `image-dired-show-all-from-dir-max-files', ask for confirmation before creating the thumbnail buffer. If that variable is nil, -never ask for confirmation." +never ask for confirmation. + +Any file matching `image-dired--file-name-regexp' is considered an +image file." (interactive "DShow thumbnails for directory: ") - (dired dir) + (dired dirname) (dired-mark-files-regexp (image-dired--file-name-regexp)) (let ((files (dired-get-marked-files nil nil nil t)) (dired-default-directory default-directory)) commit d4503ccc2769035184e474542fc6c1df7e908ae0 Author: Sacha Chua Date: Thu Jan 2 14:52:28 2025 -0500 image-dired-show-all-from-dir: Reuse dired's default-directory * lisp/image/image-dired.el (image-dired-show-all-from-dir): Delegate figuring out default-directory to dired. This handles the case where image-dired is called with a cons cell that has a directory in the car and a list of files in the cdr, which dired can handle, and therefore allows image-dired-show-all-from-dir to show an arbitrary list of images. It also means that image-dired-show-all-from-dir can handle wildcards. Ref: https://lists.gnu.org/r/emacs-devel/2025-01/msg00048.html diff --git a/lisp/image/image-dired.el b/lisp/image/image-dired.el index 71c272e4388..de548c6c729 100644 --- a/lisp/image/image-dired.el +++ b/lisp/image/image-dired.el @@ -630,7 +630,8 @@ never ask for confirmation." (interactive "DShow thumbnails for directory: ") (dired dir) (dired-mark-files-regexp (image-dired--file-name-regexp)) - (let ((files (dired-get-marked-files nil nil nil t))) + (let ((files (dired-get-marked-files nil nil nil t)) + (dired-default-directory default-directory)) (cond ((and (null (cdr files))) (message "No image files in directory")) ((or (not image-dired-show-all-from-dir-max-files) @@ -644,7 +645,7 @@ never ask for confirmation." (let ((inhibit-message t)) (dired-unmark-all-marks)) (pop-to-buffer image-dired-thumbnail-buffer) - (setq default-directory dir) + (setq default-directory dired-default-directory) (image-dired--update-header-line)) (t (message "Image-Dired canceled"))))) commit d98516a27b9ff77e1106ae5801c7ca8802eaa656 Author: Stefan Kangas Date: Mon Jan 6 20:06:49 2025 +0100 ; Silence byte-compiler diff --git a/lisp/man.el b/lisp/man.el index 9bfd9307bc7..be31d8d2489 100644 --- a/lisp/man.el +++ b/lisp/man.el @@ -2038,7 +2038,7 @@ Specify which REFERENCE to use; default is based on word at point." (defun Man-view-header-file (file) "View a header file specified by FILE from `Man-header-file-path'." - (when-let ((match (man--find-header-files file))) + (when-let* ((match (man--find-header-files file))) (view-file (car match)) (car match))) commit 15d940ad1fc3ca3a72c23d9873a32a1a68d0cb05 Author: Stefan Kangas Date: Mon Jan 6 20:03:48 2025 +0100 New test for finding C header files The assumption here is that if there is a C compiler, there is also a math.h header somewhere. The test should fail if we can't find that file, and hopefully that will provoke users to create bug reports. Let's see how far we can take this idea; we might have to give up and disable the test in some configurations. But doing that now seems premature, even if we had a list of affected systems (which we don't). * lisp/man.el (man--find-header-file): Factor out new function... (Man-view-header-file): ...from here. * test/lisp/man-tests.el (man-tests-find-header-file): New test. diff --git a/lisp/man.el b/lisp/man.el index 103131fbb34..9bfd9307bc7 100644 --- a/lisp/man.el +++ b/lisp/man.el @@ -2028,18 +2028,19 @@ Specify which REFERENCE to use; default is based on word at point." (error "You're looking at the first manpage in the buffer")))) ;; Header file support +(defun man--find-header-files (file) + (delq nil + (mapcar (lambda (path) + (let ((complete-path (expand-file-name file path))) + (and (file-readable-p complete-path) + complete-path))) + (Man-header-file-path)))) + (defun Man-view-header-file (file) "View a header file specified by FILE from `Man-header-file-path'." - (let ((path (Man-header-file-path)) - complete-path) - (while path - (setq complete-path (expand-file-name file (car path)) - path (cdr path)) - (if (file-readable-p complete-path) - (progn (view-file complete-path) - (setq path nil)) - (setq complete-path nil))) - complete-path)) + (when-let ((match (man--find-header-files file))) + (view-file (car match)) + (car match))) ;;; Bookmark Man Support (declare-function bookmark-make-record-default diff --git a/test/lisp/man-tests.el b/test/lisp/man-tests.el index 5557c423a7a..f076439e802 100644 --- a/test/lisp/man-tests.el +++ b/test/lisp/man-tests.el @@ -179,6 +179,15 @@ DESCRIPTION "\"-k\" \"basename\"" "-k basename")))) +(ert-deftest man-tests-find-header-file () + ;; We should be able to find header files on any system with a C + ;; compiler, I think. + (skip-unless (or (executable-find "cc") + (executable-find "gcc") + (executable-find "clang"))) + (should (file-exists-p (car (man--find-header-files "math.h")))) + (should-not (man--find-header-files "nonexistent-header-does-not-exist.h"))) + (provide 'man-tests) ;;; man-tests.el ends here commit 3dc3dbc2e38340aba7f818eab21abfd93a132175 Author: Stefan Kangas Date: Mon Jan 6 12:29:21 2025 +0100 Fix finding C headers with clang This fixes following "#include" references in 'M-x man' buffers, and using ffap, both on macOS machines, and on systems where for some reason clang is available but gcc is not. * lisp/subr.el (internal--c-header-file-path): Fix finding C headers with clang. (internal--gcc-is-clang-p): New function factored out from... * lisp/emacs-lisp/ert-x.el (ert-gcc-is-clang-p): ...here. * lisp/man.el (Man-header-file-path): Bump :version tag. * test/lisp/subr-tests.el (subr-tests-internal--c-header-file-path/clang-mocked): New test. diff --git a/lisp/emacs-lisp/ert-x.el b/lisp/emacs-lisp/ert-x.el index 82cc772e09c..147787d3d38 100644 --- a/lisp/emacs-lisp/ert-x.el +++ b/lisp/emacs-lisp/ert-x.el @@ -526,11 +526,7 @@ The same keyword arguments are supported as in (defun ert-gcc-is-clang-p () "Return non-nil if the `gcc' command actually runs the Clang compiler." - ;; Some macOS machines run llvm when you type gcc. (!) - ;; We can't even check if it's a symlink; it's a binary placed in - ;; "/usr/bin/gcc". So we need to check the output. - (string-match "Apple \\(LLVM\\|[Cc]lang\\)\\|Xcode\\.app" - (shell-command-to-string "gcc --version"))) + (internal--gcc-is-clang-p)) (defvar tramp-default-host-alist) (defvar tramp-methods) diff --git a/lisp/man.el b/lisp/man.el index b030e57aaf8..103131fbb34 100644 --- a/lisp/man.el +++ b/lisp/man.el @@ -232,7 +232,7 @@ the associated section number." (defcustom Man-header-file-path (internal--c-header-file-path) "C Header file search path used in Man." - :version "24.1" ; add multiarch + :version "31.1" :type '(repeat string)) (defcustom Man-name-local-regexp (concat "^" (regexp-opt '("NOM" "NAME")) "$") diff --git a/lisp/subr.el b/lisp/subr.el index 9044a92c5f5..5be8d8f52d4 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -7556,6 +7556,17 @@ and return the value found in PLACE instead." ,(funcall setter val) ,val))))) +(defun internal--gcc-is-clang-p () + "Return non-nil if the `gcc' command actually runs the Clang compiler." + ;; Recent macOS machines run llvm when you type gcc by default. (!) + ;; We can't even check if it's a symlink; it's a binary placed in + ;; "/usr/bin/gcc". So we need to check the output. + (when-let* ((out (ignore-errors + (with-temp-buffer + (call-process "gcc" nil t nil "--version") + (buffer-string))))) + (string-match "Apple \\(LLVM\\|[Cc]lang\\)\\|Xcode\\.app" out))) + (defun internal--c-header-file-path () "Return search path for C header files (a list of strings)." ;; FIXME: It's not clear that this is a good place to put this, or @@ -7563,15 +7574,41 @@ and return the value found in PLACE instead." ;; See also (Bug#10702): ;; cc-search-directories, semantic-c-dependency-system-include-path, ;; semantic-gcc-setup - (let ((arch (with-temp-buffer - (when (eq 0 (ignore-errors - (call-process "gcc" nil '(t nil) nil - "-print-multiarch"))) - (goto-char (point-min)) - (buffer-substring (point) (line-end-position))))) - (base '("/usr/include" "/usr/local/include"))) - (if (zerop (length arch)) - base - (append base (list (expand-file-name arch "/usr/include")))))) + (delete-dups + (let ((base '("/usr/include" "/usr/local/include"))) + (cond ((or (internal--gcc-is-clang-p) + (and (executable-find "clang") + (not (executable-find "gcc")))) + ;; This is either macOS, or a system with clang only. + (with-temp-buffer + (ignore-errors + (call-process (if (internal--gcc-is-clang-p) "gcc" "clang") + nil t nil + "-v" "-E" "-")) + (goto-char (point-min)) + (narrow-to-region + (save-excursion + (re-search-forward + "^#include <\\.\\.\\.> search starts here:\n" nil t) + (point)) + (save-excursion + (re-search-forward "^End of search list.$" nil t) + (pos-bol))) + (while (search-forward "(framework directory)" nil t) + (delete-line)) + (append base + (reverse + (split-string (buffer-substring-no-properties + (point-min) (point-max))))))) + ;; Prefer GCC. + ((let ((arch (with-temp-buffer + (when (eq 0 (ignore-errors + (call-process "gcc" nil '(t nil) nil + "-print-multiarch"))) + (goto-char (point-min)) + (buffer-substring (point) (line-end-position)))))) + (if (zerop (length arch)) + base + (append base (list (expand-file-name arch "/usr/include")))))))))) ;;; subr.el ends here diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index 2cb0b616074..5b17c598efa 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -1410,5 +1410,38 @@ final or penultimate step during initialization.")) (insert "x86_64-linux-gnu\n") 0)))) (should (member "/usr/include/x86_64-linux-gnu" (internal--c-header-file-path))))) +(ert-deftest subr-tests-internal--c-header-file-path/clang-mocked () + ;; Handle clang 15.0.0 output on macOS 15.2. + (cl-letf (((symbol-function 'internal--gcc-is-clang-p) (lambda () t)) + ((symbol-function 'call-process) + (lambda (_program &optional _infile _destination _display &rest _args) + (insert "\ +Apple clang version 15.0.0 (clang-1500.3.9.4) +Target: arm64-apple-darwin24.2.0 +Thread model: posix +InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin + \"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang\" +[[[...Emacs test omits some verbose junk from the output here...]]] +clang -cc1 version 15.0.0 (clang-1500.3.9.4) default target arm64-apple-darwin24.2.0 +ignoring nonexistent directory \"/usr/local/include\" +#include \"...\" search starts here: +#include <...> search starts here: + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/include + /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include + /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks (framework directory) +End of search list. +# 1 \"\" +# 1 \"\" 1 +# 1 \"\" 3 +# 418 \"\" 3 +# 1 \"\" 1 +# 1 \"\" 2 +# 1 \"\" 2") + 0))) + (should (member "/usr/include" (internal--c-header-file-path))) + (should (member "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/include" + (internal--c-header-file-path))))) + (provide 'subr-tests) ;;; subr-tests.el ends here commit 888ff3755d499ca74f9d8cdf9e4d2c7dc0331236 Author: Stefan Kangas Date: Mon Jan 6 10:08:01 2025 +0100 New function internal--c-header-file-path It is not clear to me where this function properly belongs, so let's put it in subr.el for now. This avoids code duplication without introducing a dependency between man and ffap. It can always be moved later. * lisp/subr.el (internal--c-header-file-path): New function. * lisp/man.el (Man-header-file-path): * lisp/ffap.el (ffap-c-path): Use above new function. * test/lisp/subr-tests.el (ert-x): Require. (subr-tests-internal--c-header-file-path) (subr-tests-internal--c-header-file-path/gcc-mocked): New tests. diff --git a/lisp/ffap.el b/lisp/ffap.el index c2b181b55f3..890a227fca9 100644 --- a/lisp/ffap.el +++ b/lisp/ffap.el @@ -831,22 +831,7 @@ to extract substrings.") (and (not (string-match "\\.el\\'" name)) (ffap-locate-file name '(".el") load-path))) -;; FIXME this duplicates the logic of Man-header-file-path. -;; There should be a single central variable or function for this. -;; See also (bug#10702): -;; cc-search-directories, semantic-c-dependency-system-include-path, -;; semantic-gcc-setup -(defvar ffap-c-path - (let ((arch (with-temp-buffer - (when (eq 0 (ignore-errors - (call-process "gcc" nil '(t nil) nil - "-print-multiarch"))) - (goto-char (point-min)) - (buffer-substring (point) (line-end-position))))) - (base '("/usr/include" "/usr/local/include"))) - (if (zerop (length arch)) - base - (append base (list (expand-file-name arch "/usr/include"))))) +(defvar ffap-c-path (internal--c-header-file-path) "List of directories to search for include files.") (defun ffap-c-mode (name) diff --git a/lisp/man.el b/lisp/man.el index 29c3dec501c..b030e57aaf8 100644 --- a/lisp/man.el +++ b/lisp/man.el @@ -230,18 +230,7 @@ the associated section number." :type '(repeat (cons (string :tag "Bogus Section") (string :tag "Real Section")))) -;; FIXME see comments at ffap-c-path. -(defcustom Man-header-file-path - (let ((arch (with-temp-buffer - (when (eq 0 (ignore-errors - (call-process "gcc" nil '(t nil) nil - "-print-multiarch"))) - (goto-char (point-min)) - (buffer-substring (point) (line-end-position))))) - (base '("/usr/include" "/usr/local/include"))) - (if (zerop (length arch)) - base - (append base (list (expand-file-name arch "/usr/include"))))) +(defcustom Man-header-file-path (internal--c-header-file-path) "C Header file search path used in Man." :version "24.1" ; add multiarch :type '(repeat string)) diff --git a/lisp/subr.el b/lisp/subr.el index 5646ab268a4..9044a92c5f5 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -7556,4 +7556,22 @@ and return the value found in PLACE instead." ,(funcall setter val) ,val))))) +(defun internal--c-header-file-path () + "Return search path for C header files (a list of strings)." + ;; FIXME: It's not clear that this is a good place to put this, or + ;; even that this should necessarily be internal. + ;; See also (Bug#10702): + ;; cc-search-directories, semantic-c-dependency-system-include-path, + ;; semantic-gcc-setup + (let ((arch (with-temp-buffer + (when (eq 0 (ignore-errors + (call-process "gcc" nil '(t nil) nil + "-print-multiarch"))) + (goto-char (point-min)) + (buffer-substring (point) (line-end-position))))) + (base '("/usr/include" "/usr/local/include"))) + (if (zerop (length arch)) + base + (append base (list (expand-file-name arch "/usr/include")))))) + ;;; subr.el ends here diff --git a/test/lisp/subr-tests.el b/test/lisp/subr-tests.el index e6964c42ca8..2cb0b616074 100644 --- a/test/lisp/subr-tests.el +++ b/test/lisp/subr-tests.el @@ -27,6 +27,7 @@ ;;; Code: (require 'ert) +(require 'ert-x) (eval-when-compile (require 'cl-lib)) (ert-deftest let-when-compile () @@ -1382,5 +1383,32 @@ final or penultimate step during initialization.")) (props-out (object-intervals out))) (should (equal props-out props-in)))))))) +(ert-deftest subr-tests-internal--c-header-file-path () + (should (seq-every-p #'stringp (internal--c-header-file-path))) + (should (member "/usr/include" (internal--c-header-file-path))) + (should (equal (internal--c-header-file-path) + (delete-dups (internal--c-header-file-path)))) + ;; Return a meaningful result even if calling some compiler fails. + (cl-letf (((symbol-function 'call-process) + (lambda (_program &optional _infile _destination _display &rest _args) 1))) + (should (seq-every-p #'stringp (internal--c-header-file-path))) + (should (member "/usr/include" (internal--c-header-file-path))) + (should (equal (internal--c-header-file-path) + (delete-dups (internal--c-header-file-path)))))) + +(ert-deftest subr-tests-internal--c-header-file-path/gcc-mocked () + ;; Handle empty values of "gcc -print-multiarch". + (cl-letf (((symbol-function 'call-process) + (lambda (_program &optional _infile _destination _display &rest args) + (when (equal (car args) "-print-multiarch") + (insert "\n") 0)))) + (should (member "/usr/include" (internal--c-header-file-path)))) + ;; Handle single values of "gcc -print-multiarch". + (cl-letf (((symbol-function 'call-process) + (lambda (_program &optional _infile _destination _display &rest args) + (when (equal (car args) "-print-multiarch") + (insert "x86_64-linux-gnu\n") 0)))) + (should (member "/usr/include/x86_64-linux-gnu" (internal--c-header-file-path))))) + (provide 'subr-tests) ;;; subr-tests.el ends here commit 3de5fcd0a60b01639276f360561037403f8d7389 Author: Stephen Gildea Date: Mon Jan 6 11:00:07 2025 -0800 time-stamp: lower- and title-case weekday and month names * lisp/time-stamp.el (time-stamp-string-preprocess): new formats for lowercase weekday name, lowercase month name, and system name * test/lisp/time-stamp.el: new tests (formatz-generate-tests): Better doc strings for generated test fns. diff --git a/lisp/time-stamp.el b/lisp/time-stamp.el index 0ef85da6374..fb3c6cb81da 100644 --- a/lisp/time-stamp.el +++ b/lisp/time-stamp.el @@ -52,7 +52,7 @@ with %, which are converted as follows: %H 24-hour clock hour %I 12-hour clock hour %m month number %M minute -%p `AM' or `PM' +%p meridian indicator: `AM', `PM' %S seconds %w day number of week, Sunday is 0 %Y 4-digit year %y 2-digit year @@ -67,16 +67,29 @@ Non-date items: %q unqualified host name %Q fully-qualified host name %h mail host name -A \"#\" after the % changes the case of letters. For example, on Mondays, -in the default locale, \"%#A\" converts to \"MONDAY\". +The % may be followed by a modifier affecting the letter case. +The modifier \"#\" changes the case of letters, usually to uppercase, +or if the word is already uppercase, to lowercase. +The modifier \"^\" converts letters to uppercase; +\"^\" may be followed by \"#\" to convert to lowercase. +The modifier \"*\" converts words to title case (capitalized). + +Here are some example conversions on Mondays, in two locales: + + English French +%A Monday lundi +%^A MONDAY LUNDI +%^#A monday lundi +%*A Monday Lundi Decimal digits before the type character specify the minimum field width. A \"0\" before the field width adds insignificant zeroes as appropriate, otherwise the padding is done with spaces. -If no padding is specified, a field that can be one or two digits is padded -with \"0\" to two digits if necessary. Follow the % with \"_\" to pad with a -space instead, or follow it with \"-\" to suppress this padding entirely. +If no padding is specified, a field that can be one or two digits is +padded with \"0\" to two digits if necessary. Follow the % with \"_\" +to pad with a space instead, or follow it with \"-\" to suppress this +padding entirely. Thus, on the 5th of the month, the day is converted as follows: \"%d\" -> \"05\" @@ -92,10 +105,11 @@ The examples here are for the default (\"C\") locale. `time-stamp-time-zone' controls the time zone used. Some of the conversions recommended here work only in Emacs 27 or later. +The title-case and lowercase modifiers work only in Emacs 31 or later. If your files might be edited by older versions of Emacs also, you should limit yourself to the formats recommended by that older version." :type 'string - :version "27.1") + :version "31.1") ;;;###autoload(put 'time-stamp-format 'safe-local-variable 'stringp) @@ -515,6 +529,7 @@ and all `time-stamp-format' compatibility." field-result (alt-form 0) (change-case nil) + (title-case nil) (upcase nil) (flag-pad-with-spaces nil) (flag-pad-with-zeros nil) @@ -526,7 +541,7 @@ and all `time-stamp-format' compatibility." (setq cur-char (if (< ind fmt-len) (aref format ind) ?\0)) - (or (eq ?. cur-char) (eq ?* cur-char) + (or (eq ?. cur-char) (eq ?~ cur-char) (eq ?* cur-char) (eq ?E cur-char) (eq ?O cur-char) (eq ?, cur-char) (eq ?: cur-char) (eq ?@ cur-char) (eq ?- cur-char) (eq ?+ cur-char) (eq ?_ cur-char) @@ -563,7 +578,9 @@ and all `time-stamp-format' compatibility." ((eq cur-char ?#) (setq change-case t)) ((eq cur-char ?^) - (setq upcase t)) + (setq upcase t title-case nil change-case nil)) + ((eq cur-char ?*) + (setq title-case t upcase nil change-case nil)) ((eq cur-char ?0) (setq flag-pad-with-zeros t)) ((eq cur-char ?-) @@ -572,18 +589,18 @@ and all `time-stamp-format' compatibility." (setq field-width "2" flag-pad-with-spaces t)))) (if (> (string-to-number field-width) 99) (setq field-width (if flag-pad-with-zeros "099" "99"))) - (setq field-result - (cond + (setq field-result + (cond ((eq cur-char ?%) "%") ((eq cur-char ?a) ;day of week - (if (> alt-form 0) - (if (string-equal field-width "") - (time-stamp--format "%A" time) - "") ;discourage "%:3a" - (if (or change-case upcase) - (time-stamp--format "%#a" time) - (time-stamp--format "%a" time)))) + (time-stamp-do-letter-case + nil upcase title-case change-case + (if (> alt-form 0) + (if (string-equal field-width "") + (time-stamp--format "%A" time) + "") ;discourage "%:3a" + (time-stamp--format "%a" time)))) ((eq cur-char ?A) (if (and (>= (string-to-number field-width) 1) (<= (string-to-number field-width) 3) @@ -592,24 +609,25 @@ and all `time-stamp-format' compatibility." (progn (time-stamp-conv-warn "%3A" "%#a") (time-stamp--format "%#a" time)) - (if (or change-case upcase) - (time-stamp--format "%#A" time) - (if (or (> alt-form 0) - flag-minimize flag-pad-with-spaces - (string-equal field-width "")) - (time-stamp--format "%A" time) - (time-stamp-conv-warn (format "%%%sA" field-width) - (format "%%#%sA" field-width) - (format "%%:%sA" field-width)) - (time-stamp--format "%#A" time))))) + (if (or (> alt-form 0) + change-case upcase title-case + flag-minimize flag-pad-with-spaces + (string-equal field-width "")) + (time-stamp-do-letter-case + nil upcase title-case change-case + (time-stamp--format "%A" time)) + (time-stamp-conv-warn (format "%%%sA" field-width) + (format "%%#%sA" field-width) + (format "%%:%sA" field-width)) + (time-stamp--format "%#A" time)))) ((eq cur-char ?b) ;month name - (if (> alt-form 0) - (if (string-equal field-width "") - (time-stamp--format "%B" time) - "") ;discourage "%:3b" - (if (or change-case upcase) - (time-stamp--format "%#b" time) - (time-stamp--format "%b" time)))) + (time-stamp-do-letter-case + nil upcase title-case change-case + (if (> alt-form 0) + (if (string-equal field-width "") + (time-stamp--format "%B" time) + "") ;discourage "%:3b" + (time-stamp--format "%b" time)))) ((eq cur-char ?B) (if (and (>= (string-to-number field-width) 1) (<= (string-to-number field-width) 3) @@ -618,16 +636,17 @@ and all `time-stamp-format' compatibility." (progn (time-stamp-conv-warn "%3B" "%#b") (time-stamp--format "%#b" time)) - (if (or change-case upcase) - (time-stamp--format "%#B" time) - (if (or (> alt-form 0) - flag-minimize flag-pad-with-spaces - (string-equal field-width "")) - (time-stamp--format "%B" time) - (time-stamp-conv-warn (format "%%%sB" field-width) - (format "%%#%sB" field-width) - (format "%%:%sB" field-width)) - (time-stamp--format "%#B" time))))) + (if (or (> alt-form 0) + change-case upcase title-case + flag-minimize flag-pad-with-spaces + (string-equal field-width "")) + (time-stamp-do-letter-case + nil upcase title-case change-case + (time-stamp--format "%B" time)) + (time-stamp-conv-warn (format "%%%sB" field-width) + (format "%%#%sB" field-width) + (format "%%:%sB" field-width)) + (time-stamp--format "%#B" time)))) ((eq cur-char ?d) ;day of month, 1-31 (time-stamp-do-number cur-char alt-form field-width time)) ((eq cur-char ?H) ;hour, 0-23 @@ -639,17 +658,15 @@ and all `time-stamp-format' compatibility." ((eq cur-char ?M) ;minute, 0-59 (time-stamp-do-number cur-char alt-form field-width time)) ((eq cur-char ?p) ;AM or PM - (if change-case - (time-stamp--format "%#p" time) - (if upcase - (time-stamp--format "%^p" time) - (time-stamp--format "%p" time)))) + (time-stamp-do-letter-case + t upcase title-case change-case + (time-stamp--format "%p" time))) ((eq cur-char ?P) ;AM or PM - (if change-case - (time-stamp--format "%#p" time) - (if upcase - "" ;discourage inconsistent "%^P" - (time-stamp--format "%p" time)))) + (if (and upcase (not change-case)) + "" ;discourage inconsistent "%^P" + (time-stamp-do-letter-case + t upcase title-case change-case + (time-stamp--format "%p" time)))) ((eq cur-char ?S) ;seconds, 00-60 (time-stamp-do-number cur-char alt-form field-width time)) ((eq cur-char ?w) ;weekday number, Sunday is 0 @@ -699,9 +716,9 @@ and all `time-stamp-format' compatibility." field-width-num offset-secs))))) ((eq cur-char ?Z) ;time zone name - (if change-case - (time-stamp--format "%#Z" time) - (time-stamp--format "%Z" time))) + (time-stamp-do-letter-case + t upcase title-case change-case + (time-stamp--format "%Z" time))) ((eq cur-char ?f) ;buffer-file-name, base name only (if buffer-file-name (file-name-nondirectory buffer-file-name) @@ -724,12 +741,14 @@ and all `time-stamp-format' compatibility." (user-full-name)) ((eq cur-char ?h) ;mail host name (or mail-host-address (system-name))) - ((eq cur-char ?q) ;unqualified host name - (let ((qualname (system-name))) - (if (string-match "\\." qualname) - (substring qualname 0 (match-beginning 0)) - qualname))) - ((eq cur-char ?Q) ;fully-qualified host name + ((or (eq cur-char ?q) ;unqualified host name + (eq cur-char ?x)) ;short system name, experimental + (let ((shortname (system-name))) + (if (string-match "\\." shortname) + (substring shortname 0 (match-beginning 0)) + shortname))) + ((or (eq cur-char ?Q) ;fully-qualified host name + (eq cur-char ?X)) ;full system name, experimental (system-name)) )) (and (numberp field-result) @@ -747,6 +766,28 @@ and all `time-stamp-format' compatibility." (setq ind (1+ ind))) result)) +(defun time-stamp-do-letter-case (change-is-downcase + upcase title-case change-case text) + "Apply upper- and lower-case conversions to TEXT according to the flags. +CHANGE-IS-DOWNCASE non-nil indicates that modifier CHANGE-CASE requests +lowercase, otherwise the modifier requests uppercase. +UPCASE is non-nil if the \"^\" modifier is active. +TITLE-CASE is non-nil if the \"*\" modifier is active. +CHANGE-CASE is non-nil if the \"#\" modifier is active. +This is an internal helper for `time-stamp-string-preprocess'." + (cond ((and upcase change-case) + (downcase text)) + ((and title-case change-case) + (upcase text)) + ((and change-is-downcase change-case) + (downcase text)) + ((or change-case upcase) + (upcase text)) + (title-case + (capitalize text)) + (t + text))) + (defun time-stamp-do-number (format-char alt-form field-width time) "Handle compatible FORMAT-CHAR where only default width/padding will change. ALT-FORM is whether `#' was specified. FIELD-WIDTH is the string diff --git a/test/lisp/time-stamp-tests.el b/test/lisp/time-stamp-tests.el index ddf17645f46..6858990b982 100644 --- a/test/lisp/time-stamp-tests.el +++ b/test/lisp/time-stamp-tests.el @@ -293,8 +293,12 @@ (with-time-stamp-test-env (let* ((Mon (format-time-string "%a" ref-time1 t)) (MON (format-time-string "%^a" ref-time1 t)) + (mon (downcase (format-time-string "%a" ref-time1 t))) + (Mon-tc (capitalize (format-time-string "%a" ref-time1 t))) (Monday (format-time-string "%A" ref-time1 t)) (MONDAY (format-time-string "%^A" ref-time1 t)) + (monday (downcase (format-time-string "%A" ref-time1 t))) + (Monday-tc (capitalize (format-time-string "%A" ref-time1 t))) (p4-Mon (string-pad Mon 4 ?\s t)) (p4-MON (string-pad MON 4 ?\s t)) (p10-Monday (string-pad Monday 10 ?\s t)) @@ -331,15 +335,27 @@ (should (equal (time-stamp-string "%A" ref-time1) Monday)) ;; warned 1997-2019, changed in 2019 (should (equal (time-stamp-string "%^a" ref-time1) MON)) - (should (equal (time-stamp-string "%^4a" ref-time1) p4-MON))))) + (should (equal (time-stamp-string "%^4a" ref-time1) p4-MON)) + ;; implemented since 2025 + (should (equal (time-stamp-string "%^#A" ref-time1) monday)) + (should (equal (time-stamp-string "%^#a" ref-time1) mon)) + (should (equal (time-stamp-string "%*A" ref-time1) Monday-tc)) + (should (equal (time-stamp-string "%*a" ref-time1) Mon-tc)) + ;; discouraged + (should (equal (time-stamp-string "%:3a" ref-time1) " ")) + ))) (ert-deftest time-stamp-format-month-name () "Test `time-stamp' formats for month name." (with-time-stamp-test-env (let* ((Jan (format-time-string "%b" ref-time1 t)) (JAN (format-time-string "%^b" ref-time1 t)) + (jan (downcase (format-time-string "%b" ref-time1 t))) + (Jan-tc (capitalize (format-time-string "%^b" ref-time1 t))) (January (format-time-string "%B" ref-time1 t)) (JANUARY (format-time-string "%^B" ref-time1 t)) + (january (downcase (format-time-string "%B" ref-time1 t))) + (January-tc (capitalize (format-time-string "%B" ref-time1 t))) (p4-Jan (string-pad Jan 4 ?\s t)) (p4-JAN (string-pad JAN 4 ?\s t)) (p10-January (string-pad January 10 ?\s t)) @@ -376,7 +392,15 @@ (should (equal (time-stamp-string "%B" ref-time1) January)) ;; warned 1997-2019, changed in 2019 (should (equal (time-stamp-string "%^b" ref-time1) JAN)) - (should (equal (time-stamp-string "%^4b" ref-time1) p4-JAN))))) + (should (equal (time-stamp-string "%^4b" ref-time1) p4-JAN)) + ;; implemented since 2025 + (should (equal (time-stamp-string "%^#B" ref-time1) january)) + (should (equal (time-stamp-string "%^#b" ref-time1) jan)) + (should (equal (time-stamp-string "%*B" ref-time1) January-tc)) + (should (equal (time-stamp-string "%*b" ref-time1) Jan-tc)) + ;; discouraged + (should (equal (time-stamp-string "%:3b" ref-time1) " ")) + ))) (ert-deftest time-stamp-format-day-of-month () "Test `time-stamp' formats for day of month." @@ -399,7 +423,10 @@ (should (equal (time-stamp-string "%_d" ref-time1) " 2")) (should (equal (time-stamp-string "%_d" ref-time2) "18")) (should (equal (time-stamp-string "%d" ref-time1) "02")) - (should (equal (time-stamp-string "%d" ref-time2) "18")))) + (should (equal (time-stamp-string "%d" ref-time2) "18")) + ;; discouraged + (should (equal (time-stamp-string "%:2d" ref-time1) " ")) + )) (ert-deftest time-stamp-format-hours-24 () "Test `time-stamp' formats for hour on a 24-hour clock." @@ -591,12 +618,25 @@ ;; changed in 2024 (should (equal (time-stamp-string "%^p" ref-time1) PM)) (should (equal (time-stamp-string "%^p" ref-time3) AM)) + (should (equal (time-stamp-string "%#^p" ref-time1) PM)) + (should (equal (time-stamp-string "%#^p" ref-time3) AM)) (should (equal (time-stamp-string "%#P" ref-time1) pm)) (should (equal (time-stamp-string "%#P" ref-time3) am)) (should (equal (time-stamp-string "%^#P" ref-time1) pm)) (should (equal (time-stamp-string "%^#P" ref-time3) am)) (should (equal (time-stamp-string "%^P" ref-time1) "")) - (should (equal (time-stamp-string "%^P" ref-time3) ""))))) + (should (equal (time-stamp-string "%^P" ref-time3) "")) + ;; reserved for possible adding or removing periods (dots) + (should (equal (time-stamp-string "%:p" ref-time1) Pm)) + (should (equal (time-stamp-string "%#:p" ref-time1) pm)) + (should (equal (time-stamp-string "%^:p" ref-time1) PM)) + (should (equal (time-stamp-string "%.p" ref-time1) Pm)) + (should (equal (time-stamp-string "%#.p" ref-time1) pm)) + (should (equal (time-stamp-string "%^.p" ref-time1) PM)) + (should (equal (time-stamp-string "%@p" ref-time1) Pm)) + (should (equal (time-stamp-string "%#@p" ref-time1) pm)) + (should (equal (time-stamp-string "%^@p" ref-time1) PM)) + ))) (ert-deftest time-stamp-format-day-number-in-week () "Test `time-stamp' formats for day number in week." @@ -674,17 +714,26 @@ ;; implemented since 2007, recommended since 2019 (should (equal (time-stamp-string "%Q" ref-time1) "test-system-name.example.org")) - (should (equal (time-stamp-string "%q" ref-time1) "test-system-name"))) + (should (equal (time-stamp-string "%q" ref-time1) "test-system-name")) + ;; implemented since 2025 + (should (equal (time-stamp-string "%X" ref-time1) + "test-system-name.example.org")) + (should (equal (time-stamp-string "%x" ref-time1) "test-system-name"))) (with-time-stamp-system-name "sysname-no-dots" + ;; implemented since 2007, recommended since 2019 (should (equal (time-stamp-string "%Q" ref-time1) "sysname-no-dots")) - (should (equal (time-stamp-string "%q" ref-time1) "sysname-no-dots"))))) + (should (equal (time-stamp-string "%q" ref-time1) "sysname-no-dots")) + ;; implemented since 2025 + (should (equal (time-stamp-string "%X" ref-time1) "sysname-no-dots")) + (should (equal (time-stamp-string "%x" ref-time1) "sysname-no-dots")) + ))) (ert-deftest time-stamp-format-ignored-modifiers () "Test additional args allowed (but ignored) to allow for future expansion." (with-time-stamp-test-env (let ((May (format-time-string "%B" ref-time3 t))) ;; allowed modifiers - (should (equal (time-stamp-string "%.,@+*EO (stuff)B" ref-time3) May)) + (should (equal (time-stamp-string "%.,@+~EO (stuff)B" ref-time3) May)) ;; parens nest (should (equal (time-stamp-string "%(st(u)ff)B" ref-time3) May)) ;; escaped parens do not change the nesting level @@ -761,6 +810,14 @@ (should (equal (time-stamp-string "%-Z" ref-time1) UTC-abbr)) (should (equal (time-stamp-string "%_Z" ref-time1) UTC-abbr))))) +(ert-deftest time-stamp-format-letter-case () + "Test `time-stamp' upcase and downcase modifiers not tested elsewhere." + (with-time-stamp-test-env + (let ((MONDAY (format-time-string "%^A" ref-time1 t))) + (should (equal (time-stamp-string "%*^A" ref-time1) MONDAY)) + (should (equal (time-stamp-string "%*#A" ref-time1) MONDAY)) + ))) + ;;; Tests of helper functions (ert-deftest time-stamp-helper-string-defaults () @@ -1008,14 +1065,19 @@ the other expected results for hours greater than 99 with non-zero seconds." ;; Generate a form to create a list of tests to define. When this ;; macro is called, the form is evaluated, thus defining the tests. ;; We will modify this list, so start with a list consed at runtime. - (let ((ert-test-list (list 'list))) + (let ((ert-test-list (list 'list)) + (common-description + (concat "\nThis test expands from a call to" + " the macro `formatz-generate-tests'.\n" + "To find the specific call, search the source file for \""))) (dolist (form-string form-strings ert-test-list) (nconc ert-test-list (list `(ert-deftest ,(intern (concat "formatz-" form-string "-hhmm")) () - ,(concat "Test time-stamp format " form-string - " with whole hours or minutes.") + ,(concat "Test `time-stamp' format " form-string + " with whole hours and whole minutes.\n" + common-description form-string "\".") (should (equal (formatz ,form-string (fz-make+zone 0)) ,(car hour-mod))) (formatz-hours-exact-helper ,form-string ',(cdr hour-mod)) @@ -1023,14 +1085,16 @@ 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 "Test time-stamp format " form-string - " with offsets that have non-zero seconds.") + ,(concat "Test `time-stamp' format " form-string + " with offsets that have non-zero seconds.\n" + common-description form-string "\".") (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 "Test time-stamp format " form-string - " with offsets that are 100 hours or greater.") + ,(concat "Test `time-stamp' format " form-string + " with offsets of 100 hours or greater.\n" + common-description form-string "\".") (should (equal (formatz ,form-string (fz-make+zone 100)) ,(car big-mod))) (formatz-hours-big-helper ,form-string ',(cdr big-mod)) commit 997b9b8d38fd8a770fb1e0b3c85abae2c0d6cdd3 Author: Juri Linkov Date: Mon Jan 6 20:02:18 2025 +0200 * lisp/treesit.el: Use forward-list-default-function for C-M-n (treesit--forward-list-with-default): New internal function with body from 'treesit-forward-sexp-list' (bug#73404). (treesit-forward-sexp-list, treesit-forward-list): Replace body with a call to the shared implementation 'treesit--forward-list-with-default' using the corresponding default function as an argument. diff --git a/lisp/treesit.el b/lisp/treesit.el index 49135fd90df..9dd8419b32f 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -2469,18 +2469,12 @@ across atoms (such as symbols or words) inside the list." ;; then functions like `up-list' will signal "at top level". (treesit--scan-error pred arg)))) -(defun treesit-forward-sexp-list (&optional arg) - "Alternative tree-sitter implementation for `forward-sexp-function'. - -Whereas `treesit-forward-sexp' moves across both lists and atoms -using `sexp' in `treesit-thing-settings', this function uses -`sexp-list' in `treesit-thing-settings' to move only across lists. -But to move across atoms (such as symbols or words) inside the list -it uses `forward-sexp-default-function' as long as it doesn't go -outside of the boundaries of the current list. +(defun treesit--forward-list-with-default (arg default-function) + "Move forward across a list. +Fall back to DEFAULT-FUNCTION as long as it doesn't cross +the boundaries of the list. -ARG is described in the docstring of `forward-sexp-function'." - (interactive "^p") +ARG is described in the docstring of `forward-list'." (let* ((pred (or treesit-sexp-type-regexp 'sexp-list)) (arg (or arg 1)) (cnt arg) @@ -2489,7 +2483,7 @@ ARG is described in the docstring of `forward-sexp-function'." (let* ((default-pos (condition-case _ (save-excursion - (forward-sexp-default-function inc) + (funcall default-function inc) (point)) (scan-error nil))) (sibling (if (> arg 0) @@ -2497,7 +2491,7 @@ ARG is described in the docstring of `forward-sexp-function'." (treesit-thing-prev (point) pred))) (current (when default-pos (treesit-thing-at (point) pred t)))) - ;; Use 'forward-sexp-default-function' only if it doesn't go + ;; Use the default function only if it doesn't go ;; over the sibling and doesn't go out of the current group. (or (when (and default-pos (or (null sibling) @@ -2506,8 +2500,8 @@ ARG is described in the docstring of `forward-sexp-function'." (>= default-pos (treesit-node-end sibling)))) (or (null current) (if (> arg 0) - (< default-pos (treesit-node-end current)) - (> default-pos (treesit-node-start current))))) + (<= default-pos (treesit-node-end current)) + (>= default-pos (treesit-node-start current))))) (goto-char default-pos)) (when sibling (goto-char (if (> arg 0) @@ -2516,6 +2510,20 @@ ARG is described in the docstring of `forward-sexp-function'." (treesit--scan-error pred arg))) (setq cnt (- cnt inc))))) +(defun treesit-forward-sexp-list (&optional arg) + "Alternative tree-sitter implementation for `forward-sexp-function'. + +Whereas `treesit-forward-sexp' moves across both lists and atoms +using `sexp' in `treesit-thing-settings', this function uses +`sexp-list' in `treesit-thing-settings' to move only across lists. +But to move across atoms (such as symbols or words) inside the list +it uses `forward-sexp-default-function' as long as it doesn't go +outside of the boundaries of the current list. + +ARG is described in the docstring of `forward-sexp-function'." + (interactive "^p") + (treesit--forward-list-with-default arg 'forward-sexp-default-function)) + (defun treesit-forward-list (&optional arg) "Move forward across a list. What constitutes a list is determined by `sexp-list' in @@ -2525,17 +2533,12 @@ parentheses-like expressions. Unlike `forward-sexp', this command moves only across a list, but not across atoms (such as symbols or words) inside the list. -This command is the tree-sitter variant of `forward-list' -redefined by the variable `forward-list-function'. +It uses `forward-list-default-function' as long as it doesn't go +outside of the boundaries of the current list. -ARG is described in the docstring of `forward-list'." +ARG is described in the docstring of `forward-list-function'." (interactive "^p") - (let ((arg (or arg 1)) - (pred 'sexp-list)) - (or (if (> arg 0) - (treesit-end-of-thing pred (abs arg) 'restricted) - (treesit-beginning-of-thing pred (abs arg) 'restricted)) - (treesit--scan-error pred arg)))) + (treesit--forward-list-with-default arg 'forward-list-default-function)) (defun treesit-down-list (&optional arg) "Move forward down one level of parentheses. commit c3ec174a6c2d1118e82aecceb203634f7b567e20 Author: João Távora Date: Mon Jan 6 10:47:13 2025 +0000 Eglot: new eglot--format to fix quote substitution woes (bug#73472) * lisp/progmodes/eglot.el (eglot--guess-contact): Use eglot--format. (eglot--format): New helper. (eglot--error, eglot--message, eglot--warn) (eglot--apply-text-edits, eglot-rename): Use eglot--format. diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index 3d0ba747c46..858946d6cc4 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -1325,16 +1325,19 @@ be guessed." (and base-prompt (cond (current-prefix-arg base-prompt) ((null guess) - (format "[eglot] Couldn't guess LSP server for `%s'\n%s" - main-mode base-prompt)) + (eglot--format + "[eglot] Couldn't guess LSP server for `%s'\n%s" + main-mode base-prompt)) ((and program (not (file-name-absolute-p program)) (not (compat-call executable-find program t))) (if full-program-invocation - (concat (format "[eglot] I guess you want to run `%s'" - full-program-invocation) - (format ", but I can't find `%s' in PATH!" - program) + (concat (eglot--format + "[eglot] I guess you want to run `%s'" + full-program-invocation) + (eglot--format + ", but I can't find `%s' in PATH!" + program) "\n" base-prompt) (eglot--error (concat "`%s' not found in PATH, but can't form" @@ -1702,19 +1705,23 @@ in project `%s'." ;;; Helpers (move these to API?) ;;; +(defun eglot--format (format &rest args) + "Like `format`, but substitutes quotes." + (apply #'format (substitute-quotes format) args)) + (defun eglot--error (format &rest args) "Error out with FORMAT with ARGS." - (error "[eglot] %s" (apply #'format format args))) + (error "[eglot] %s" (apply #'eglot--format format args))) (defun eglot--message (format &rest args) "Message out with FORMAT with ARGS." - (message "[eglot] %s" (apply #'format format args))) + (message "[eglot] %s" (apply #'eglot--format format args))) (defun eglot--warn (format &rest args) "Warning message with FORMAT and ARGS." (apply #'eglot--message (concat "(warning) " format) args) (let ((warning-minimum-level :error)) - (display-warning 'eglot (apply #'format format args) :warning))) + (display-warning 'eglot (apply #'eglot--format format args) :warning))) (defalias 'eglot--bol (if (fboundp 'pos-bol) #'pos-bol @@ -3595,7 +3602,7 @@ If SILENT, don't echo progress in mode-line." (howmany (length edits)) (reporter (unless silent (make-progress-reporter - (format "[eglot] applying %s edits to `%s'..." + (eglot--format "[eglot] applying %s edits to `%s'..." howmany (current-buffer)) 0 howmany))) (done 0)) @@ -3717,8 +3724,9 @@ edit proposed by the server." "Rename the current symbol to NEWNAME." (interactive (list (read-from-minibuffer - (format "Rename `%s' to: " (or (thing-at-point 'symbol t) - "unknown symbol")) + (eglot--format "Rename `%s' to: " + (or (thing-at-point 'symbol t) + "unknown symbol")) nil nil nil nil (symbol-name (symbol-at-point))))) (eglot-server-capable-or-lose :renameProvider) commit da5df90fadbec9db692ff34abcd28ce5a5b29c2a Author: Stefan Kangas Date: Mon Jan 6 11:07:09 2025 +0100 Improve integer file mode options docstrings * lisp/eshell/esh-util.el (eshell-private-file-modes) (eshell-private-directory-modes): * lisp/gnus/mail-source.el (mail-source-default-file-modes): * lisp/printing.el (pr-file-modes): * lisp/gnus/mm-decode.el (mm-attachment-file-modes): * lisp/gnus/nnmail.el (nnmail-default-file-modes): * lisp/recentf.el (recentf-save-file-modes): * lisp/vc/ediff-init.el (ediff-temp-file-mode): * lisp/vc/emerge.el (emerge-temp-file-mode): Better document the fact that these are integer and not octal values. * lisp/epg.el (epg--start): * lisp/emacs-lisp/package.el (package-import-keyring): Use octal values to make the code more self-documenting. diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index 9e62f0a5c0d..3abce17a3e8 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -1751,7 +1751,7 @@ The variable `package-load-list' controls which packages to load." (setq file (expand-file-name file)) (let ((context (epg-make-context 'OpenPGP))) (when package-gnupghome-dir - (with-file-modes 448 + (with-file-modes #o700 (make-directory package-gnupghome-dir t)) (setf (epg-context-home-directory context) package-gnupghome-dir)) (message "Importing %s..." (file-name-nondirectory file)) diff --git a/lisp/epg.el b/lisp/epg.el index 385e5a7f7c8..c796230b12c 100644 --- a/lisp/epg.el +++ b/lisp/epg.el @@ -670,7 +670,7 @@ callback data (if any)." :noquery t)) (setf (epg-context-error-buffer context) (process-buffer error-process)) (with-existing-directory - (with-file-modes 448 + (with-file-modes #o700 (setq process (make-process :name "epg" :buffer buffer :command (cons (epg-context-program context) diff --git a/lisp/eshell/esh-util.el b/lisp/eshell/esh-util.el index 189be5fe57c..bc2e04746b1 100644 --- a/lisp/eshell/esh-util.el +++ b/lisp/eshell/esh-util.el @@ -64,11 +64,13 @@ Setting this to nil is offered as an aid to debugging only." :type 'boolean) (defcustom eshell-private-file-modes #o600 ; umask 177 - "The file-modes value to use for creating \"private\" files." + "The file-modes value to use for creating \"private\" files. +This is decimal, not octal. The default is 384 (0600 in octal)." :type 'integer) (defcustom eshell-private-directory-modes #o700 ; umask 077 - "The file-modes value to use for creating \"private\" directories." + "The file-modes value to use for creating \"private\" directories. +This is decimal, not octal. The default is 448 (0700 in octal)." :type 'integer) (defcustom eshell-tar-regexp diff --git a/lisp/gnus/mail-source.el b/lisp/gnus/mail-source.el index 838ba7dac77..eece03a62bc 100644 --- a/lisp/gnus/mail-source.el +++ b/lisp/gnus/mail-source.el @@ -246,8 +246,9 @@ If non-nil, this maildrop will be checked periodically for new mail." "Directory where incoming mail source files (if any) will be stored." :type 'directory) -(defcustom mail-source-default-file-modes 384 - "Set the mode bits of all new mail files to this integer." +(defcustom mail-source-default-file-modes #o600 + "Set the mode bits of all new mail files to this integer. +This is decimal, not octal. The default is 384 (0600 in octal)." :type 'integer) (defcustom mail-source-delete-incoming diff --git a/lisp/gnus/mm-decode.el b/lisp/gnus/mm-decode.el index 33d08b4677a..6aab997b892 100644 --- a/lisp/gnus/mm-decode.el +++ b/lisp/gnus/mm-decode.el @@ -442,8 +442,9 @@ If not set, `default-directory' will be used." :type '(choice directory (const :tag "Default" nil)) :group 'mime-display) -(defcustom mm-attachment-file-modes 384 - "Set the mode bits of saved attachments to this integer." +(defcustom mm-attachment-file-modes #o600 + "Set the mode bits of saved attachments to this integer. +This is decimal, not octal. The default is 384 (0600 in octal)." :version "22.1" :type 'integer :group 'mime-display) diff --git a/lisp/gnus/nnmail.el b/lisp/gnus/nnmail.el index 966078659f7..e580d7aebba 100644 --- a/lisp/gnus/nnmail.el +++ b/lisp/gnus/nnmail.el @@ -152,8 +152,9 @@ If nil, groups like \"mail.misc\" will end up in directories like :group 'nnmail-files :type 'boolean) -(defcustom nnmail-default-file-modes 384 - "Set the mode bits of all new mail files to this integer." +(defcustom nnmail-default-file-modes #o600 + "Set the mode bits of all new mail files to this integer. +This is decimal, not octal. The default is 384 (0600 in octal)." :group 'nnmail-files :type 'integer) diff --git a/lisp/printing.el b/lisp/printing.el index 0d7013a30cf..c84ee54eb7f 100644 --- a/lisp/printing.el +++ b/lisp/printing.el @@ -1814,9 +1814,9 @@ See also `pr-temp-dir' and `pr-file-modes'." ;; It uses 0600 as default instead of (default-file-modes). ;; So, by default, only the session owner have permission to deal with files ;; generated by `printing'. -(defcustom pr-file-modes ?\600 +(defcustom pr-file-modes #o600 "Specify the file permission bits for newly created files. - +This is decimal, not octal. The default is 384 (0600 in octal). It should be an integer; only the low 9 bits are used. See also `pr-temp-dir' and `pr-ps-temp-file'." diff --git a/lisp/recentf.el b/lisp/recentf.el index 58f03e0c615..a282fbee3b1 100644 --- a/lisp/recentf.el +++ b/lisp/recentf.el @@ -96,9 +96,10 @@ See the command `recentf-save-list'." (defcustom recentf-save-file-modes #o600 "Mode bits of recentf save file, as an integer, or nil. -If non-nil, after writing `recentf-save-file', set its mode bits to -this value. By default give R/W access only to the user who owns that -file. See also the function `set-file-modes'." +If non-nil, after writing `recentf-save-file', set its mode bits to this +value. This is decimal, not octal. The default is 384 (0600 in octal), +which gives R/W access only to the user who owns that file. See also +the function `set-file-modes'." :group 'recentf :type '(choice (const :tag "Don't change" nil) integer)) diff --git a/lisp/vc/ediff-init.el b/lisp/vc/ediff-init.el index 03f280d080f..d67785d96fa 100644 --- a/lisp/vc/ediff-init.el +++ b/lisp/vc/ediff-init.el @@ -1218,8 +1218,9 @@ Instead, C-h would jump to previous difference." (define-obsolete-variable-alias 'ediff-temp-file-prefix 'temporary-file-directory "28.1") -(defcustom ediff-temp-file-mode 384 ; u=rw only - "Mode for Ediff temporary files." +(defcustom ediff-temp-file-mode #o0600 + "Mode for Ediff temporary files. +This is decimal, not octal. The default is 384 (0600 in octal)." :type 'integer :group 'ediff) diff --git a/lisp/vc/emerge.el b/lisp/vc/emerge.el index ca48f2f3c7b..45405028df9 100644 --- a/lisp/vc/emerge.el +++ b/lisp/vc/emerge.el @@ -233,8 +233,9 @@ Do not start with `~/' or `~USERNAME/'." "customize `temporary-file-directory' instead." "24.4" 'set) -(defcustom emerge-temp-file-mode 384 ; u=rw only - "Mode for Emerge temporary files." +(defcustom emerge-temp-file-mode #o600 + "Mode for Emerge temporary files. +This is decimal, not octal. The default is 384 (0600 in octal)." :type 'integer) (make-obsolete-variable 'emerge-temp-file-mode commit 6a389d5be47d1c143054a69e7302371d3889d658 Author: Peter Oliver Date: Wed Jul 17 00:06:02 2024 +0100 Try harder to stabilize dired-test-bug27243-02 * test/lisp/dired-tests.el (dired-test-bug27243-02): Don't rely on the expected point, since columns will move if the size of the parent directory changes order of magnitude. (Bug#72120) diff --git a/test/lisp/dired-tests.el b/test/lisp/dired-tests.el index 4fb99b9b728..be585d276ec 100644 --- a/test/lisp/dired-tests.el +++ b/test/lisp/dired-tests.el @@ -190,7 +190,6 @@ "Test for https://debbugs.gnu.org/cgi/bugreport.cgi?bug=27243#28 ." (ert-with-temp-directory test-dir (let ((dired-auto-revert-buffer t) - (dired-free-space nil) buffers) ;; On MS-Windows, get rid of 8+3 short names in test-dir, if the ;; corresponding long file names exist, otherwise such names trip @@ -216,7 +215,9 @@ ;; Sanity check: point should now be back on the subdirectory. (should (eq (point) pt1)) (push (dired test-dir) buffers) - (should (eq (point) pt1))) + (should (equal (dired-file-name-at-point) + (concat (file-name-as-directory test-dir) + (file-name-as-directory "test-subdir"))))) (dolist (buf buffers) (when (buffer-live-p buf) (kill-buffer buf))))))) commit f652566af51079428526a3312512214b82ed8728 Author: Stefan Kangas Date: Mon Jan 6 10:06:17 2025 +0100 ; Silence byte-compiler * test/lisp/net/browse-url-tests.el (browse-url-tests-delete-temp-file): Suppress warning. diff --git a/test/lisp/net/browse-url-tests.el b/test/lisp/net/browse-url-tests.el index 45339284fd6..337d127434f 100644 --- a/test/lisp/net/browse-url-tests.el +++ b/test/lisp/net/browse-url-tests.el @@ -104,7 +104,8 @@ (browse-url-delete-temp-file) (should-not (file-exists-p browse-url-temp-file-name))) (ert-with-temp-file file - (browse-url-delete-temp-file file) + (with-suppressed-warnings ((callargs browse-url-delete-temp-file)) + (browse-url-delete-temp-file file)) (should-not (file-exists-p file)))) (ert-deftest browse-url-tests-add-buttons () commit 1096d9afaa19799fade32ebada5b16add593511f Author: Stefan Kangas Date: Mon Jan 6 06:33:19 2025 +0100 Improve Commentary in man.el * lisp/man.el (Commentary): Move "Features" above "Credits and History". The former is more likely to be relevant. diff --git a/lisp/man.el b/lisp/man.el index a3af03c7601..29c3dec501c 100644 --- a/lisp/man.el +++ b/lisp/man.el @@ -1,7 +1,6 @@ ;;; man.el --- browse UNIX manual pages -*- lexical-binding: t -*- -;; Copyright (C) 1993-1994, 1996-1997, 2001-2025 Free Software -;; Foundation, Inc. +;; Copyright (C) 1993-2025 Free Software Foundation, Inc. ;; Author: Barry A. Warsaw ;; Maintainer: emacs-devel@gnu.org @@ -30,9 +29,22 @@ ;; can continue to use your Emacs while processing is going on. ;; ;; The mode also supports hypertext-like following of manual page SEE -;; ALSO references, and other features. See below or do `?' in a +;; ALSO references, and other features. See below or type `?' in a ;; manual page buffer for details. +;; ========== Features ========== +;; + Runs "man" in the background and pipes the results through a +;; series of sed and awk scripts so that all retrieving and cleaning +;; is done in the background. The cleaning commands are configurable. +;; + Syntax is the same as Un*x man +;; + Functionality is the same as Un*x man, including "man -k" and +;; "man
", etc. +;; + Provides a manual browsing mode with keybindings for traversing +;; the sections of a manpage, following references in the SEE ALSO +;; section, and more. +;; + Multiple manpages created with the same man command are put into +;; a narrowed buffer circular list. + ;; ========== Credits and History ========== ;; In mid 1991, several people posted some interesting improvements to ;; man.el from the standard Emacs 18.57 distribution. I liked many of @@ -59,19 +71,6 @@ ;; making it faster, more robust and more tolerant of different ;; systems' man idiosyncrasies. -;; ========== Features ========== -;; + Runs "man" in the background and pipes the results through a -;; series of sed and awk scripts so that all retrieving and cleaning -;; is done in the background. The cleaning commands are configurable. -;; + Syntax is the same as Un*x man -;; + Functionality is the same as Un*x man, including "man -k" and -;; "man
", etc. -;; + Provides a manual browsing mode with keybindings for traversing -;; the sections of a manpage, following references in the SEE ALSO -;; section, and more. -;; + Multiple manpages created with the same man command are put into -;; a narrowed buffer circular list. - ;; ============= TODO =========== ;; - Add a command for printing. ;; - The awk script deletes multiple blank lines. This behavior does commit fe6a28acaca4bc24883dff04aec0f9e6097b7466 Author: Stefan Kangas Date: Mon Jan 6 06:40:12 2025 +0100 ; Quote function symbols in man.el * lisp/man.el (Man-init-defvars, Man-translate-references) (Man-highlight-references, Man-page-from-arguments) (Man-follow-manual-reference): Quote function symbols. diff --git a/lisp/man.el b/lisp/man.el index ed97606f7e2..a3af03c7601 100644 --- a/lisp/man.el +++ b/lisp/man.el @@ -623,7 +623,7 @@ This is necessary if one wants to dump man.el with Emacs." (setq Man-filter-list ;; Avoid trailing nil which confuses customize. - (apply 'list + (apply #'list (cons Man-sed-command (if (eq system-type 'windows-nt) @@ -754,7 +754,7 @@ and the `Man-section-translations-alist' variables)." section (match-string 1 ref)))) (if (string= name "") ;; see Bug#66390 - (mapconcat 'identity + (mapconcat #'identity (mapcar #'shell-quote-argument (split-string ref "\\s-+")) " ") ; Return the reference as is @@ -1434,13 +1434,13 @@ default type, `Man-xref-man-page' is used for the buttons." (if (string-match "-k " Man-arguments) (progn (Man-highlight-references0 nil Man-reference-regexp 1 - 'Man-default-man-entry + #'Man-default-man-entry (or xref-man-type 'Man-xref-man-page)) (Man-highlight-references0 nil Man-apropos-regexp 1 - 'Man-default-man-entry + #'Man-default-man-entry (or xref-man-type 'Man-xref-man-page))) (Man-highlight-references0 Man-see-also-regexp Man-reference-regexp 1 - 'Man-default-man-entry + #'Man-default-man-entry (or xref-man-type 'Man-xref-man-page)) (Man-highlight-references0 Man-synopsis-regexp Man-header-regexp 0 2 'Man-xref-header-file) @@ -1648,7 +1648,7 @@ manpage command." (defun Man-page-from-arguments (args) ;; Skip arguments and only print the page name. (mapconcat - 'identity + #'identity (delete nil (mapcar (lambda (elem) @@ -1970,7 +1970,7 @@ Specify which REFERENCE to use; default is based on word at point." Man--last-refpage (car Man--refpages)))) (defaults - (mapcar 'substring-no-properties + (mapcar #'substring-no-properties (cons default Man--refpages))) (prompt (format-prompt "Refer to" default)) (chosen (completing-read prompt Man--refpages commit 04a8faef0948f46b16172855ee337f59819f22a7 Author: João Távora Date: Sun Jan 5 20:39:51 2025 +0000 Eglot: fix signature precedence based on provenance (bug#74914) * lisp/progmodes/eglot.el (eglot--sig-info): Reverse order of activeParameter and sig-active. diff --git a/lisp/progmodes/eglot.el b/lisp/progmodes/eglot.el index d4e40791e86..3d0ba747c46 100644 --- a/lisp/progmodes/eglot.el +++ b/lisp/progmodes/eglot.el @@ -3426,7 +3426,7 @@ for which LSP on-type-formatting should be requested." 'font-lock-function-name-face)))) ;; Now to the parameters (cl-loop - with active-param = (or sig-active activeParameter) + with active-param = (or activeParameter sig-active) for i from 0 for parameter across parameters do (eglot--dbind ((ParameterInformation) ((:label parlabel)) commit 127fc983080a3b9a607fa693bacfcf02f19ce0b7 Author: Stefan Monnier Date: Sun Jan 5 10:03:40 2025 -0500 (hack-one-local-variable): Fix bug#74964 * lisp/files.el (hack-local-variables--inhibit): New var. (hack-one-local-variable): Use it to avoid infinite recursion in a more targeted manner. diff --git a/lisp/files.el b/lisp/files.el index 72128ea4af2..b0f6440fdce 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -4490,11 +4490,15 @@ It is dangerous if either of these conditions are met: (substitute-command-keys instead) (format-message "use `%s' instead" instead))))))) +(defvar hack-local-variables--inhibit nil + "List of file/dir local variables to ignore.") + (defun hack-one-local-variable (var val) "Set local variable VAR with value VAL. If VAR is `mode', call `VAL-mode' as a function unless it's already the major mode." (pcase var + ((guard (memq var hack-local-variables--inhibit)) nil) ('mode (let ((mode (intern (concat (downcase (symbol-name val)) "-mode")))) @@ -4502,7 +4506,8 @@ already the major mode." ('eval (pcase val (`(add-hook ',hook . ,_) (hack-one-local-variable--obsolete hook))) - (let ((enable-local-variables nil)) ;FIXME: Should be buffer-local! + (let ((hack-local-variables--inhibit ;; FIXME: Should be buffer-local! + (cons 'eval hack-local-variables--inhibit))) (save-excursion (eval val t)))) (_ (hack-one-local-variable--obsolete var) commit 672a5f2b82c3c57b753902f2bdf5c970f3fc63a9 Author: Michael Albinus Date: Sun Jan 5 15:24:21 2025 +0100 * lisp/net/tramp-sh.el (tramp-get-remote-pipe-buf): Make it more robust. diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 823ff81cb56..40013852153 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -5633,6 +5633,7 @@ Nonexistent directories are removed from spec." ;; - 8 KiB on HP-UX, Plan9. ;; - 10 KiB on IRIX. ;; - 32 KiB on AIX, Minix. +;; - `undefined' on QNX. ;; [1] https://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html ;; [2] https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html ;; See Bug#65324. @@ -5640,11 +5641,13 @@ Nonexistent directories are removed from spec." (defun tramp-get-remote-pipe-buf (vec) "Return PIPE_BUF config from the remote side." (with-tramp-connection-property vec "pipe-buf" - (tramp-send-command-and-read - vec - (format "getconf PIPE_BUF / 2>%s || echo 4096" - (tramp-get-remote-null-device vec)) - 'noerror))) + (if-let* ((result + (tramp-send-command-and-read + vec (format "getconf PIPE_BUF / 2>%s" + (tramp-get-remote-null-device vec)) + 'noerror)) + ((natnump result))) + result 4096))) (defun tramp-get-remote-locale (vec) "Determine remote locale, supporting UTF8 if possible." commit bc1a544b524f0c11a131f34a81a11fc59b1fdd1e Author: viliaapro Date: Tue Dec 31 14:07:43 2024 +0200 Fix bug in 'rng-valid' that unnecessarily marks buffer as modified * lisp/nxml/rng-valid.el (rng-do-some-validation-1): Use 'with-silent-modifications'. (Bug#75224) Copyright-paperwork-exempt: yes diff --git a/lisp/nxml/rng-valid.el b/lisp/nxml/rng-valid.el index a4795d3b1a0..3407618b258 100644 --- a/lisp/nxml/rng-valid.el +++ b/lisp/nxml/rng-valid.el @@ -545,7 +545,8 @@ Return t if there is work to do, nil otherwise." ((or (>= pos next-cache-point) (not continue)) (setq next-cache-point (+ pos rng-state-cache-distance)) - (rng-clear-cached-state remove-start pos) + (with-silent-modifications + (rng-clear-cached-state remove-start pos)) (when have-remaining-chars (rng-cache-state (1- pos))) (setq remove-start pos) commit c6d0c2eec389fb140ba01f4a821315375d3f662f Author: Eli Zaretskii Date: Sun Jan 5 14:41:43 2025 +0200 ; * admin/authors.el (authors-aliases): Add William O'Brien. diff --git a/admin/authors.el b/admin/authors.el index 838862241c0..d38e8ff9a66 100644 --- a/admin/authors.el +++ b/admin/authors.el @@ -294,6 +294,7 @@ files.") (nil "vjoki@") (nil "whatacold@gmail\\.com") ("William M. Perry" "Bill Perry") + ("William O'Brien" "will\\.08rien@gmail.com") ("Włodzimierz Bzyl" "W.*dek Bzyl") (nil "xyblor") ("Yilkal Argaw" "yilkalargaw" "yilkalargawworkneh@gmail\\.com") commit ac3b67860761f0b80e6fd4071d1ec868a9f6b083 Author: w08r Date: Thu Dec 19 09:53:02 2024 +0000 Enable extra flags in 'go-ts-mode' test commands * lisp/progmodes/go-ts-mode.el (go-ts-mode-test-flags): (go-ts-mode--get-test-flags): New custom variable and function for controlling test behaviour. (go-ts-mode--compile-test): Updated to use new test flags variable for passing extra information to the go test command line. (go-ts-mode-test-this-package): Updated to use new test flags variable for passing extra information to the go test command line. Removed incorrect use of -run flag. * etc/NEWS: Announce the new user option. (Bug#74786) diff --git a/etc/NEWS b/etc/NEWS index 0f27cddb050..00e9e1871cd 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -548,6 +548,10 @@ package of the current buffer. It is bound to 'C-c C-t p' in 'go-ts-mode'. The 'go-ts-mode-build-tags' user option is available to set a list of build tags for the test commands. +The 'go-ts-mode-test-flags' user option is available to set a list of +additional flags to pass to the go test command line. + + ** C-ts mode +++ diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el index 1ea49e72f07..747bf9a9da8 100644 --- a/lisp/progmodes/go-ts-mode.el +++ b/lisp/progmodes/go-ts-mode.el @@ -53,6 +53,12 @@ :type '(repeat string) :group 'go) +(defcustom go-ts-mode-test-flags nil + "List of extra flags for the Go test commands." + :version "31.1" + :type '(repeat string) + :group 'go) + (defvar go-ts-mode--syntax-table (let ((table (make-syntax-table))) (modify-syntax-entry ?+ "." table) @@ -393,13 +399,20 @@ specifying build tags." (format "-tags %s" (string-join go-ts-mode-build-tags ",")) "")) +(defun go-ts-mode--get-test-flags () + "Return the flags for test invocation." + (if go-ts-mode-test-flags + (mapconcat #'shell-quote-argument go-ts-mode-test-flags " ") + "")) + (defun go-ts-mode--compile-test (regexp) "Compile the tests matching REGEXP. This function respects the `go-ts-mode-build-tags' variable for specifying build tags." - (compile (format "go test -v %s -run '%s'" + (compile (format "go test -v %s -run '%s' %s" (go-ts-mode--get-build-tags-flag) - regexp))) + regexp + (go-ts-mode--get-test-flags)))) (defun go-ts-mode--find-defun-at (start) "Return the first defun node from START." @@ -458,9 +471,10 @@ be run." (defun go-ts-mode-test-this-package () "Run all the unit tests under the current package." (interactive) - (compile (format "go test -v %s -run %s" + (compile (format "go test -v %s %s %s" (go-ts-mode--get-build-tags-flag) - default-directory))) + default-directory + (go-ts-mode--get-test-flags)))) ;; go.mod support. commit dc41ddb4d6bd7dc45cb9c37bc89c8c08f256baec Author: Eli Zaretskii Date: Sun Jan 5 12:40:39 2025 +0200 Allow to remap 'header-line' face * src/xfaces.c (realize_basic_faces): Bind 'face-remapping-alist' to nil while realizing basic faces. (lookup_basic_face): Force realizing a face whose 'inherit' attribute is non-nil. (Bug#73862) diff --git a/src/xfaces.c b/src/xfaces.c index 75fe73154ca..5c1300309dd 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -5146,10 +5146,19 @@ lookup_basic_face (struct window *w, struct frame *f, int face_id) for the very common no-remapping case. */ mapping = assq_no_quit (name, Vface_remapping_alist); if (NILP (mapping)) - return face_id; /* Give up. */ + { + Lisp_Object face_attrs[LFACE_VECTOR_SIZE]; + + /* If the face inherits from another, we need to realize it, + because the parent face could be remapped. */ + if (!get_lface_attributes (w, f, name, face_attrs, false, 0) + || NILP (face_attrs[LFACE_INHERIT_INDEX]) + || UNSPECIFIEDP (face_attrs[LFACE_INHERIT_INDEX])) + return face_id; /* Give up. */ + } - /* If there is a remapping entry, lookup the face using NAME, which will - handle the remapping too. */ + /* If there is a remapping entry, or the face inherits from another, + lookup the face using NAME, which will handle the remapping too. */ remapped_face_id = lookup_named_face (w, f, name, false); if (remapped_face_id < 0) return face_id; /* Give up. */ @@ -5866,6 +5875,12 @@ realize_basic_faces (struct frame *f) if (realize_default_face (f)) { + /* Basic faces must be realized disregarding face-remapping-alist, + since otherwise face-remapping might affect the basic faces in the + face cache, if this function happens to be invoked with current + buffer set to a buffer with a non-nil face-remapping-alist. */ + specpdl_ref count = SPECPDL_INDEX (); + specbind (Qface_remapping_alist, Qnil); realize_named_face (f, Qmode_line_active, MODE_LINE_ACTIVE_FACE_ID); realize_named_face (f, Qmode_line_inactive, MODE_LINE_INACTIVE_FACE_ID); realize_named_face (f, Qtool_bar, TOOL_BAR_FACE_ID); @@ -5887,6 +5902,7 @@ realize_basic_faces (struct frame *f) realize_named_face (f, Qchild_frame_border, CHILD_FRAME_BORDER_FACE_ID); realize_named_face (f, Qtab_bar, TAB_BAR_FACE_ID); realize_named_face (f, Qtab_line, TAB_LINE_FACE_ID); + unbind_to (count, Qnil); /* Reflect changes in the `menu' face in menu bars. */ if (FRAME_FACE_CACHE (f)->menu_face_changed_p) commit 7eb8596ff5f1964f91664a6b7cac3199a5af5ba7 Author: Eli Zaretskii Date: Sun Jan 5 11:03:07 2025 +0200 ; Fix warnings in a tty-only build on MS-Windows * lisp/org/org.el (dnd-open-local-file): * lisp/dired.el (tool-bar--image-expression): * lisp/term/android-win.el (x-handle-args): Declare. * lisp/w32-fns.el (w32-system-shells): (w32-allow-system-shell): * lisp/net/shr.el (image-scaling-factor): * lisp/net/eww.el (image-scaling-factor): * lisp/image.el (image-scaling-factor): Defvar. (image-recompute-map-p): Move to before the first use. Reported by Angelo Graziosi . diff --git a/lisp/dired.el b/lisp/dired.el index d8ad74d3fd1..bab5e833a76 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -5268,6 +5268,7 @@ Interactively with prefix argument, read FILE-NAME." (declare-function Man-getpage-in-background "man" (topic)) (defvar Man-support-remote-systems) ; from man.el (defvar manual-program) ; from man.el +(declare-function tool-bar--image-expression "tool-bar" (icon)) (defun dired-do-man () "In Dired, run `man' on this file." diff --git a/lisp/image.el b/lisp/image.el index 8174b898fef..40d1364430f 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -158,6 +158,11 @@ or \"ffmpeg\") is installed." :type 'boolean :version "27.1") +(defcustom image-recompute-map-p t + "Recompute image map when scaling, rotating, or flipping an image." + :type 'boolean + :version "30.1") + (define-error 'unknown-image-type "Unknown image type") (defvar-keymap image-slice-map @@ -608,6 +613,7 @@ properties specific to certain image types." (declare (gv-setter image--set-property)) (plist-get (cdr image) property)) +(defvar image-scaling-factor) (defun image-compute-scaling-factor (&optional scaling) "Compute the scaling factor based on SCALING. If a number, use that. If it's `auto', compute the factor. @@ -1416,11 +1422,6 @@ is recomputed to fit the newly transformed image." ;;; Map transformation -(defcustom image-recompute-map-p t - "Recompute image map when scaling, rotating, or flipping an image." - :type 'boolean - :version "30.1") - (defsubst image--compute-rotation (image) "Return the current rotation of IMAGE, or 0 if no rotation. Also return nil if rotation is not a multiples of 90 degrees (0, 90, diff --git a/lisp/net/eww.el b/lisp/net/eww.el index 95513a67acd..0c23ebc19cd 100644 --- a/lisp/net/eww.el +++ b/lisp/net/eww.el @@ -1422,6 +1422,7 @@ within text input fields." (declare-function imagep "image.c") (defvar text-scale-mode) (defvar text-scale-mode-amount) +(defvar image-scaling-factor) (defun eww--rescale-images () (let ((scaling (if text-scale-mode (+ 1 (* text-scale-mode-amount 0.1)) diff --git a/lisp/net/shr.el b/lisp/net/shr.el index 24c779524dc..8cc95ea6966 100644 --- a/lisp/net/shr.el +++ b/lisp/net/shr.el @@ -1276,6 +1276,7 @@ not, `imagemagick' is preferred if it's present." nil 'imagemagick)) +(defvar image-scaling-factor) (defun shr-rescale-image (data content-type width height &optional max-width max-height) "Rescale DATA, if too big, to fit the current buffer. diff --git a/lisp/org/org.el b/lisp/org/org.el index 6a8a45a9e4f..a11eee94297 100644 --- a/lisp/org/org.el +++ b/lisp/org/org.el @@ -20917,6 +20917,8 @@ URLS is a list of file URL." (put 'org--dnd-multi-local-file-handler 'dnd-multiple-handler t) +(declare-function dnd-open-local-file "dnd" (uri action)) + (defun org--dnd-local-file-handler (url action &optional separator) "Handle file URL as per ACTION. SEPARATOR is the string to insert after each link. It may be nil diff --git a/lisp/term/android-win.el b/lisp/term/android-win.el index 3529124d2be..8e58f8911a0 100644 --- a/lisp/term/android-win.el +++ b/lisp/term/android-win.el @@ -42,6 +42,7 @@ (add-to-list 'display-format-alist '(".*" . android)) (declare-function android-get-connection "androidfns.c") +(declare-function x-handle-args "common-win" (args)) ;; Window system initialization. This is extremely simple because all ;; initialization is done in android_term_init. diff --git a/lisp/w32-fns.el b/lisp/w32-fns.el index d7958d3762b..5a4c5f52ab4 100644 --- a/lisp/w32-fns.el +++ b/lisp/w32-fns.el @@ -49,6 +49,8 @@ (and (fboundp 'w32-using-nt) (w32-using-nt) "cmd.exe") "command.com")) +(defvar w32-system-shells) ;; defined in w32-vars.el +(defvar w32-allow-system-shell) ;; defined in w32-vars.el (defun w32-system-shell-p (shell-name) (and shell-name (member (downcase (file-name-nondirectory shell-name))