commit 5dc0981875b64f2ffe38e59871cc34db05ab5f18 (HEAD, refs/remotes/origin/master) Author: Ulrich Müller Date: Thu Mar 13 21:06:01 2025 +0100 New configure option --with-systemduserunitdir * configure.ac (systemduserunitdir): New variable and option. * Makefile.in (systemduserunitdir): New, set by configure. (install-etc, uninstall): Don't install emacs.service when systemduserunitdir is unspecified. * etc/NEWS: Announce the new configure option. (Bug#76924) diff --git a/Makefile.in b/Makefile.in index ca6d991bce6..0ba11c9aa5b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -160,7 +160,7 @@ sharedstatedir=@sharedstatedir@ # a subdirectory of this. libexecdir=@libexecdir@ -# Currently only used for the systemd service file. +# Where to install object code libraries. Used for ELN_DESTDIR. libdir=@libdir@ # Where to install emacs-module.h. @@ -207,15 +207,7 @@ desktopdir=$(datarootdir)/applications metainfodir=$(datarootdir)/metainfo # Where the etc/emacs.service file is to be installed. -# The system value (typically /usr/lib/systemd/user) can be -# obtained with: pkg-config --variable=systemduserunitdir systemd -# but that does not respect configure's prefix. -# It is not clear where we should install this file when -# prefix != /usr (or /usr/local?) (eg for non-root installs). -# Other options include ~/.config/systemd/user/, -# $XDG_RUNTIME_DIR/systemd/user/ -# It seems the user may end up having to make a manual link... -systemdunitdir=$(libdir)/systemd/user +systemduserunitdir=@systemduserunitdir@ # Where the etc/images/icons/hicolor directory is to be installed. icondir=$(datarootdir)/icons @@ -886,14 +878,16 @@ install-etc: ${srcdir}/etc/emacs.metainfo.xml > $${tmp}; \ ${INSTALL_DATA} $${tmp} "$(DESTDIR)${metainfodir}/${EMACS_NAME}.metainfo.xml"; \ rm -f $${tmp} - umask 022; $(MKDIR_P) "$(DESTDIR)$(systemdunitdir)" + ifneq ($(systemduserunitdir),) + umask 022; $(MKDIR_P) "$(DESTDIR)$(systemduserunitdir)" tmp=etc/emacs.tmpservice; rm -f $${tmp}; \ sed -e '/^##/d' \ -e "/^Documentation/ s/emacs(1)/${EMACS_NAME}(1)/" \ -e "/^ExecStart/ s|emacs|${bindir}/${EMACS}|" \ ${srcdir}/etc/emacs.service > $${tmp}; \ - $(INSTALL_DATA) $${tmp} "$(DESTDIR)$(systemdunitdir)/${EMACS_NAME}.service"; \ + $(INSTALL_DATA) $${tmp} "$(DESTDIR)$(systemduserunitdir)/${EMACS_NAME}.service"; \ rm -f $${tmp} + endif thisdir=`pwd -P`; \ cd ${iconsrcdir} || exit 1; umask 022 ; \ for dir in */*/apps */*/mimetypes; do \ @@ -977,7 +971,9 @@ uninstall: uninstall-$(NTDIR) uninstall-doc uninstall-gsettings-schemas fi) -rm -f "$(DESTDIR)${desktopdir}/${EMACS_NAME}.desktop" -rm -f "$(DESTDIR)${metainfodir}/${EMACS_NAME}.metainfo.xml" - -rm -f "$(DESTDIR)$(systemdunitdir)/${EMACS_NAME}.service" + ifneq ($(systemduserunitdir),) + -rm -f "$(DESTDIR)$(systemduserunitdir)/${EMACS_NAME}.service" + endif ifneq (,$(use_gamedir)) for file in snake-scores tetris-scores; do \ file="$(DESTDIR)${gamedir}/$${file}"; \ diff --git a/configure.ac b/configure.ac index 4a7f326ab2b..81a247a696c 100644 --- a/configure.ac +++ b/configure.ac @@ -481,6 +481,24 @@ AC_SUBST([HAVE_PDUMPER]) DUMPING=$with_dumping AC_SUBST([DUMPING]) +dnl Where the etc/emacs.service file is to be installed. +dnl We use $(prefix)/lib/systemd/user as default, but this may not be +dnl in systemd's search path when prefix is neither /usr nor /usr/local. +dnl In that case (e.g. for non-root installs) the location can be +dnl specified with the configure option. +dnl See https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html#id-1.8.5 +dnl for documentation of systemd's unit file load path. +AC_ARG_WITH([systemduserunitdir], + [AS_HELP_STRING([--with-systemduserunitdir=DIR], + [directory for systemd user unit file; + default 'PREFIX/usr/lib/systemd/user'])], + [systemduserunitdir=${withval}], + [systemduserunitdir='${prefix}/lib/systemd/user']) +if test "${systemduserunitdir}" = "no"; then + systemduserunitdir='' +fi +AC_SUBST([systemduserunitdir]) + dnl FIXME currently it is not the last. dnl This should be the last --with option, because --with-x is dnl added later on when we find the file name of X, and it's best to diff --git a/etc/NEWS b/etc/NEWS index 9515ac993ee..7467af6055c 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -37,6 +37,11 @@ host system supports SSE2) or '-fno-tree-sra' (if not). These GCC options work around GCC bug 58416, which can cause Emacs to behave incorrectly in rare cases. +--- +** New configure option '--with-systemduserunitdir'. +This allows to specify the directory where the user unit file for +systemd is installed; default is '${prefix}/usr/lib/systemd/user'. + * Startup Changes in Emacs 31.1 commit f2f1fb7fe00d6d69fc081f423c1f9dff0f618e36 Merge: 89441e12e2a defc55bb6f9 Author: Yuan Fu Date: Thu Mar 13 20:18:03 2025 -0700 Merge from origin/emacs-30 defc55bb6f9 Fix treesit-parser-create behavior regarding indirect buf... 20ac26e6751 ; Fix with-delayed-message docstring metavars. 04034cd9ce7 Fix 'dired-movement-style' in Dired when subdirs are shown f8443dffc1f ; * lisp/register.el (register-use-preview): Doc fix (bug... f729828bcfb ; Add texinfo reference to GNU Coding Standards. a6abb88fdcc ; * lisp/files.el (executable-find): Doc fix. # Conflicts: # src/treesit.c commit defc55bb6f954276a1cb9e3b5c50251ba5e5b40f (refs/remotes/origin/emacs-30) Author: Yuan Fu Date: Thu Mar 13 00:33:47 2025 -0700 Fix treesit-parser-create behavior regarding indirect buffers The previous fix fixed the problem that treesit-parser-create always use the current buffer, but that introduce another subtle problem: if an indirect buffer creates a parser, the parser saves the base buffer rather than the indirect buffer. In Emacs 29, if you create a parser in an indirect buffer, the parser saves the indirect buffer. This change of behavior breaks some existing use-cases for people using indirect buffer with tree-sitter. In Emacs 31, indirect buffers and base buffer get their own parser list, so this problem doesn't exist anymore. The fix is only for Emacs 30. * src/treesit.c (Ftreesit_parser_create): Use the buffer that's given to treesit-parser-create, even if it's an indirect buffer. diff --git a/src/treesit.c b/src/treesit.c index f234698defd..3a0e9674f65 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -1560,6 +1560,9 @@ an indirect buffer. */) CHECK_BUFFER (buffer); buf = XBUFFER (buffer); } + + struct buffer *buffer_given = buf; + if (buf->base_buffer) buf = buf->base_buffer; @@ -1595,7 +1598,7 @@ an indirect buffer. */) /* Create parser. */ Lisp_Object lisp_buf; - XSETBUFFER (lisp_buf, buf); + XSETBUFFER (lisp_buf, buffer_given); Lisp_Object lisp_parser = make_treesit_parser (lisp_buf, parser, NULL, language, tag); commit 89441e12e2a25d43d1d5567ac356a7ecb8193063 Author: Eli Zaretskii Date: Thu Mar 13 22:19:14 2025 +0200 Fix aborts and text corruption in 'replace-buffer-contents' * src/insdel.c (replace_range): Fix a thinko. Fix commentary. (Bug#76997) diff --git a/src/insdel.c b/src/insdel.c index 3707342d2c4..9b770725971 100644 --- a/src/insdel.c +++ b/src/insdel.c @@ -1409,7 +1409,11 @@ adjust_after_insert (ptrdiff_t from, ptrdiff_t from_byte, adjust_after_replace (from, from_byte, Qnil, newlen, len_byte); } -/* Replace the text from character positions FROM to TO with NEW, +/* Replace the text from character positions FROM to TO with NEW. + NEW could either be a string, the replacement text, or a vector + [BUFFER BEG END], where BUFFER is the buffer with the replacement + text and BEG and END are buffer positions in BUFFER that give the + replacement text beginning and end. If PREPARE, call prepare_to_modify_buffer. If INHERIT, the newly inserted text should inherit text properties from the surrounding non-deleted text. @@ -1419,9 +1423,7 @@ adjust_after_insert (ptrdiff_t from, ptrdiff_t from_byte, /* Note that this does not yet handle markers quite right. Also it needs to record a single undo-entry that does a replacement rather than a separate delete and insert. - That way, undo will also handle markers properly. - - But if MARKERS is 0, don't relocate markers. */ + That way, undo will also handle markers properly. */ void replace_range (ptrdiff_t from, ptrdiff_t to, Lisp_Object new, @@ -1504,9 +1506,19 @@ replace_range (ptrdiff_t from, ptrdiff_t to, Lisp_Object new, insend_bytes = insend; } insbytes = insend_bytes - insbeg_bytes; + /* Move gap out of the replacement text, to arrange for + replacement text to be contiguous in the source buffer, so that + we could copy it in one go. */ if (insbuf->text->gpt_byte > insbeg_bytes && insbuf->text->gpt_byte < insend_bytes) - move_gap_both (insbeg, insbeg_bytes); + { + struct buffer *old = current_buffer; + if (insbuf != old) + set_buffer_internal (insbuf); + move_gap_both (insbeg, insbeg_bytes); + if (insbuf != old) + set_buffer_internal (old); + } insbeg_ptr = BUF_BYTE_ADDRESS (insbuf, insbeg_bytes); eassert (insbuf->text->gpt_byte <= insbeg_bytes || insbuf->text->gpt_byte >= insend_bytes); commit 59a67dcde4ecf8b8c346164f2d2cf90905762350 Author: Juri Linkov Date: Thu Mar 13 20:44:54 2025 +0200 Handle narrowed buffers in treesit-forward-sentence (bug#76679) * lisp/treesit.el (treesit-forward-sentence): When no more sentences are found, move to the end of the buffer or to the range boundary at the 'treesit-parser' overlay's end. diff --git a/lisp/treesit.el b/lisp/treesit.el index 6fdc24ba939..46332cb1e4b 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -3418,9 +3418,16 @@ What constitutes as text and source code sentence is determined by `text' and `sentence' in `treesit-thing-settings'." (if (treesit-node-match-p (treesit-node-at (point)) 'text t) (funcall #'forward-sentence-default-function arg) - (funcall - (if (> arg 0) #'treesit-end-of-thing #'treesit-beginning-of-thing) - 'sentence (abs arg)))) + (or (funcall + (if (> arg 0) #'treesit-end-of-thing #'treesit-beginning-of-thing) + 'sentence (abs arg)) + ;; On failure jump to the buffer's end as `forward-sentence' does, + ;; but no further than the boundary of the current range. + (goto-char (if (> arg 0) + (min (point-max) (next-single-char-property-change + (point) 'treesit-parser)) + (max (point-min) (previous-single-char-property-change + (point) 'treesit-parser))))))) (defun treesit-forward-comment (&optional count) "Tree-sitter `forward-comment-function' implementation. commit d1ce9fbf49bfacd00f1d1f152b457367c88d28df Author: Juri Linkov Date: Thu Mar 13 20:29:50 2025 +0200 Support more embedded ranges in treesit-up-list and treesit-outline-level * lisp/treesit.el (treesit-up-list, treesit-outline-level): Add a loop to handle all nested parsers. diff --git a/lisp/treesit.el b/lisp/treesit.el index 26a3d2f7a41..6fdc24ba939 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -3132,13 +3132,14 @@ ARG is described in the docstring of `up-list'." (treesit-node-start parent)))) (setq parent (treesit-parent-until parent pred))) - (when-let* ((_ (null parent)) - (parser (treesit-node-parser (treesit-node-at (point)))) - (_ (not (eq parser treesit-primary-parser))) - (guest-root-node (treesit-parser-root-node parser))) - ;; Continue from the host node that contains the guest parser. - (setq parent (treesit-thing-at - (- (treesit-node-start guest-root-node) 2) pred))) + (unless parent + (let ((parsers (seq-keep (lambda (o) + (overlay-get o 'treesit-host-parser)) + (overlays-at (point) t)))) + (while (and (not parent) parsers) + (setq parent (treesit-parent-until + (treesit-node-at (point) (car parsers)) pred) + parsers (cdr parsers))))) (or (when (and default-pos (or (null parent) @@ -4017,16 +4018,17 @@ For BOUND, MOVE, BACKWARD, LOOKING-AT, see the descriptions in treesit-outline-predicate))) (while (setq node (treesit-parent-until node pred)) (setq level (1+ level))) - ;; Continue counting from the host node. - (when-let* ((parser - (when treesit-aggregated-outline-predicate - (seq-some (lambda (o) (overlay-get o 'treesit-host-parser)) - (overlays-at (point))))) - (node (treesit-node-at (point) parser)) - (lang (treesit-parser-language parser)) - (pred (alist-get lang treesit-aggregated-outline-predicate))) - (while (setq node (treesit-parent-until node pred)) - (setq level (1+ level)))) + + ;; Continue counting the host nodes. + (dolist (parser (seq-keep (lambda (o) + (overlay-get o 'treesit-host-parser)) + (overlays-at (point) t))) + (let* ((node (treesit-node-at (point) parser)) + (lang (treesit-parser-language parser)) + (pred (alist-get lang treesit-aggregated-outline-predicate))) + (while (setq node (treesit-parent-until node pred)) + (setq level (1+ level))))) + level)) ;;; Hideshow mode commit abeeb6eb748652b48124fa34db718f7c749b4d8b Author: Juri Linkov Date: Thu Mar 13 20:25:29 2025 +0200 * lisp/textmodes/css-mode.el (css-ts-mode--outline-predicate): Improve. Set separate value that differs from 'css--treesit-simple-imenu-settings' by adding new node "at_rule". diff --git a/lisp/textmodes/css-mode.el b/lisp/textmodes/css-mode.el index 9437170673e..02c3618d281 100644 --- a/lisp/textmodes/css-mode.el +++ b/lisp/textmodes/css-mode.el @@ -1824,7 +1824,13 @@ rgb()/rgba()." "Settings for `treesit-simple-imenu'.") (defvar css-ts-mode--outline-predicate - (nth 1 (car css--treesit-simple-imenu-settings)) + (rx bos (or "rule_set" + "media_statement" + "keyframes_statement" + "keyframe_block" + "supports_statement" + "at_rule") + eos) "Predicate for `treesit-outline-predicate'.") (defvar css--treesit-defun-type-regexp commit 8298bbada4fdef9415c552e691d2d4791d0e51ca Author: Mauro Aranda Date: Thu Mar 13 15:19:05 2025 -0300 Fix error when trying to recommend setopt * lisp/help-fns.el (help--recommend-setopt): Don't assume that variable-documentation stores only strings. (Bug#76994) diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 2d0da178a4c..1af37df3792 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -875,7 +875,8 @@ the C sources, too." (when (and (get symbol 'custom-set) ;; Don't override manually written documentation. (not (string-match (rx word-start "setopt" word-end) - (get symbol 'variable-documentation)))) + (documentation-property + symbol 'variable-documentation)))) ;; FIXME: `princ` removes text properties added by s-c-k. (princ (substitute-command-keys "\ Setting this variable with `setq' has no effect; use either `setopt' commit f9d805cef3ef9a9818ef09e77c4379d23c2afb55 Author: Basil L. Contovounesios Date: Thu Mar 13 13:37:25 2025 +0100 ; Fix recent defvar-local docstring metavars. diff --git a/lisp/subr.el b/lisp/subr.el index c027fea5caa..689f6c362a9 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -196,7 +196,7 @@ pair. "Define SYMBOL as a buffer-local variable with default value VALUE. Like `defvar' but additionally marks the variable as being automatically buffer-local wherever it is set. -\n(fn symbol &optional value docstring)" +\n(fn SYMBOL &optional VALUE DOCSTRING)" (declare (debug defvar) (doc-string 3) (indent 2)) ;; Can't use backquote here, it's too early in the bootstrap. (let ((value (car-safe args)) commit 20ac26e6751664b08636d16e515abfa1b8419a2d Author: Basil L. Contovounesios Date: Thu Mar 13 13:36:19 2025 +0100 ; Fix with-delayed-message docstring metavars. diff --git a/lisp/subr.el b/lisp/subr.el index 42706397674..87a06575de7 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -7343,7 +7343,7 @@ not a list, return a one-element list containing OBJECT." The MESSAGE form will be evaluated immediately, but the resulting string will be displayed only if BODY takes longer than TIMEOUT seconds. -\(fn (timeout message) &rest body)" +\(fn (TIMEOUT MESSAGE) &rest BODY)" (declare (indent 1)) `(funcall-with-delayed-message ,(car args) ,(cadr args) (lambda () commit cecaec20e7ad525719d7d05233f1e6e2ba6a1475 Author: Eli Zaretskii Date: Thu Mar 13 13:35:54 2025 +0200 Allow control of indicating empty rectangular selections * lisp/rect.el (rectangle-indicate-zero-width-rectangle): New user option. (rectangle--highlight-for-redisplay): Use it to decide whether to indicate empty rectangles on display. (Bug#16403) * etc/NEWS: Announce the feature. diff --git a/etc/NEWS b/etc/NEWS index 39b2199564d..9515ac993ee 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -681,6 +681,14 @@ were also dynamically accumulated in minibuffer history during minibuffer use, they are now saved only once in the file specified by 'savehist-file'. Previously, they were saved twice. +** Rectangle Mark +--- +*** New user option to control whether empty rectangle selections are shown. +The new user option 'rectangle-indicate-zero-width-rectangle' can be +used to disable the default display of empty rectangular selections. +The default is t; set it to nil to disable the indication (which causes +a horizontal shift of text on display, and thus could be annoying). + ** Message --- diff --git a/lisp/rect.el b/lisp/rect.el index be99a3398df..e630f801558 100644 --- a/lisp/rect.el +++ b/lisp/rect.el @@ -456,6 +456,11 @@ With a prefix (or a FILL) argument, also fill too short lines." :version "25.1" :type 'boolean) +(defcustom rectangle-indicate-zero-width-rectangle t + "If non-nil, make zero-width rectangles visible on display." + :version "31.1" + :type 'boolean) + (defun rectangle--string-preview () (when rectangle-preview (let ((str (minibuffer-contents))) @@ -960,7 +965,8 @@ Ignores `line-move-visual'." (overlay-put ol 'after-string str)))) ((overlay-get ol 'after-string) (overlay-put ol 'after-string nil))) - (when (and (= leftcol rightcol) (display-graphic-p)) + (when (and (= leftcol rightcol) (display-graphic-p) + rectangle-indicate-zero-width-rectangle) ;; Make zero-width rectangles visible! (overlay-put ol 'after-string (concat (propertize commit 04034cd9ce746e3914daa66add34c66ad2db032d Author: Eli Zaretskii Date: Thu Mar 13 12:34:23 2025 +0200 Fix 'dired-movement-style' in Dired when subdirs are shown * lisp/dired.el (dired--move-to-next-line): Don't consider sub-directory lines as empty. (Bug#76596) diff --git a/lisp/dired.el b/lisp/dired.el index 90d944c5dd4..17c8ba5f123 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -2888,15 +2888,19 @@ is controlled by `dired-movement-style'." (setq wrapped t)) ;; `bounded': go back to the last non-empty line. (dired-movement-style ; Either 'bounded or anything else non-nil. - (while (and (dired-between-files) (not (zerop arg))) + (while (and (dired-between-files) + (not (dired-get-subdir)) + (not (zerop arg))) (funcall jumpfun (- moving-down)) ;; Point not moving means infinite loop. (if (= old-position (point)) (setq arg 0) (setq old-position (point)))) ;; Encountered a boundary, so let's stop movement. - (setq arg (if (dired-between-files) 0 moving-down))))) - (unless (dired-between-files) + (setq arg (if (and (dired-between-files) + (not (dired-get-subdir))) + 0 moving-down))))) + (unless (and (dired-between-files) (not (dired-get-subdir))) ;; Has moved to a non-empty line. This movement does ;; make sense. (cl-decf arg moving-down)) commit d29e0add71d6b7058930527194b8227233e50c3a Author: Eli Zaretskii Date: Thu Mar 13 12:21:28 2025 +0200 ; Fix last change (bug#75543) * lisp/textmodes/remember.el (remember-initial-major-mode) (remember-data-files-regex): Fix :version and doc strings. * etc/NEWS: Fix last added entries. diff --git a/etc/NEWS b/etc/NEWS index d90d9953b28..39b2199564d 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1452,15 +1452,15 @@ change the selection rules. ** Remember --- -*** `remember-mode' is now a minor mode. -The `remember' command enables the major mode set in -`remember-initial-major-mode' and then the `remember-mode' minor mode in -the `remember-buffer'. This allows users to customize the major mode +*** Remember mode is now a minor mode. +The 'remember' command enables the major mode set in +'remember-initial-major-mode' and then the 'remember-mode' minor mode in +the 'remember-buffer'. This allows users to customize the major mode used to write notes. --- *** New handler that append remember data in directory. -The `remember-append-in-data-directory' handler appends remember data in +The 'remember-append-in-data-directory' handler appends remember data in a file, that file being choosen by the user through the minibuffer. --- diff --git a/lisp/textmodes/remember.el b/lisp/textmodes/remember.el index 7a378fed68e..ac0dd384dda 100644 --- a/lisp/textmodes/remember.el +++ b/lisp/textmodes/remember.el @@ -185,8 +185,8 @@ (defcustom remember-initial-major-mode 'text-mode "Major mode to use in the `remember-buffer'." :type '(choice (const :tag "Use `initial-major-mode'" nil) - (function :tag "Major mode" text-mode)) - :version "31.0") + (function :tag "Major mode" text-mode)) + :version "31.1") (defcustom remember-mode-hook nil "Functions run upon entering `remember-mode'." @@ -484,10 +484,10 @@ The file is named by calling `format-time-string' using (defcustom remember-data-files-regex nil "Regular expression for specifying which files to append data. -If non-nil, keep only files whose non-directory part match the regexp. +If non-nil, keep only files whose non-directory part matches the regexp. Used by `remember-append-in-data-directory'." :type '(choice (const :tag "Any file" nil) regexp) - :version "31.0") + :version "31.1") (defun remember-append-in-data-directory () "Append remember data to a file in `remember-data-directory'. @@ -709,6 +709,7 @@ is non-nil, bury it and return nil; otherwise return t." ;; Prefix map +(defvar remember-prefix-map) (define-prefix-command 'remember-prefix-map) ;; Use with for example: ;; (keymap-global-set "C-c r" 'remember-prefix-map) commit e937167253208c7e9d22350795e72818dfa2f35b Author: Matthias Meulien Date: Mon Jan 13 23:04:54 2025 +0100 Turn 'remember-mode' into a minor mode * lisp/textmodes/remember.el (remember-initial-major-mode): Major mode for remember buffer. (remember-data-files-regex): Regular expression to filter files. (remember-append-in-data-directory): Handler to append data to files. (remember-mode): Change to a minor mode. (remember-prefix-map): New. (Bug#75543) diff --git a/etc/NEWS b/etc/NEWS index d79080c94e8..d90d9953b28 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1449,6 +1449,26 @@ Major-mode authors can customize the variables 'yank-media-autoselect-function' and/or 'yank-media-preferred-types' to change the selection rules. +** Remember + +--- +*** `remember-mode' is now a minor mode. +The `remember' command enables the major mode set in +`remember-initial-major-mode' and then the `remember-mode' minor mode in +the `remember-buffer'. This allows users to customize the major mode +used to write notes. + +--- +*** New handler that append remember data in directory. +The `remember-append-in-data-directory' handler appends remember data in +a file, that file being choosen by the user through the minibuffer. + +--- +*** New prefix map for remember commands. +Meant to be given a global binding convenient to the user. Example: + + (keymap-global-set "C-c M-r" 'remember-prefix-map) + ** Miscellaneous --- diff --git a/lisp/textmodes/remember.el b/lisp/textmodes/remember.el index f04e0603885..7a378fed68e 100644 --- a/lisp/textmodes/remember.el +++ b/lisp/textmodes/remember.el @@ -182,6 +182,12 @@ ;;; User Variables: +(defcustom remember-initial-major-mode 'text-mode + "Major mode to use in the `remember-buffer'." + :type '(choice (const :tag "Use `initial-major-mode'" nil) + (function :tag "Major mode" text-mode)) + :version "31.0") + (defcustom remember-mode-hook nil "Functions run upon entering `remember-mode'." :type 'hook @@ -210,7 +216,8 @@ recorded somewhere by that function." :options '(remember-store-in-mailbox remember-append-to-file remember-store-in-files - remember-diary-extract-entries)) + remember-diary-extract-entries + remember-append-in-data-directory)) (defcustom remember-all-handler-functions nil "If non-nil every function in `remember-handler-functions' is called." @@ -283,6 +290,8 @@ With a prefix or a visible region, use the region as INITIAL." (set-window-dedicated-p (get-buffer-window (current-buffer) (selected-frame)) t)) (setq buffer-offer-save t) + (funcall (or remember-initial-major-mode + initial-major-mode)) (remember-mode) (when (= (point-max) (point-min)) (when initial (insert initial)) @@ -450,7 +459,8 @@ If you want to remember a region, supply a universal prefix to (defcustom remember-data-directory "~/remember" "The directory in which to store remember data as files. -Used by `remember-store-in-files'." +Used by `remember-store-in-files' and +`remember-append-in-data-directory'." :type 'directory :version "24.4") @@ -472,6 +482,28 @@ The file is named by calling `format-time-string' using (write-file (convert-standard-filename (format "%s/%s" remember-data-directory name)))))) +(defcustom remember-data-files-regex nil + "Regular expression for specifying which files to append data. +If non-nil, keep only files whose non-directory part match the regexp. +Used by `remember-append-in-data-directory'." + :type '(choice (const :tag "Any file" nil) regexp) + :version "31.0") + +(defun remember-append-in-data-directory () + "Append remember data to a file in `remember-data-directory'. +The file name is read from minibuffer. + +If you want to filter proposed files, configure +`remember-data-files-regex'." + (let* ((name + (completing-read "Remember in file: " + (directory-files + (expand-file-name remember-data-directory) + nil + remember-data-files-regex))) + (remember-data-file (expand-file-name name remember-data-directory))) + (remember-append-to-file))) + ;;;###autoload (defun remember-clipboard () "Remember the contents of the current clipboard. @@ -560,15 +592,20 @@ If this is nil, then `diary-file' will be used instead." "C-c C-c" #'remember-finalize "C-c C-k" #'remember-destroy) -(define-derived-mode remember-mode text-mode "Remember" - "Major mode for output from \\[remember]. +(define-minor-mode remember-mode + "Minor mode for output from \\[remember]. This buffer is used to collect data that you want to remember. \\ Just hit \\[remember-finalize] when you're done entering, and it will file the data away for latter retrieval, and possible indexing. \\{remember-mode-map}" - (set-keymap-parent remember-mode-map nil)) + :lighter " Remember" + :keymap remember-mode-map + (setq header-line-format + (substitute-command-keys + "Edit, then exit with `\\[remember-finalize]' or abort with \ + `\\[remember-destroy]'"))) ;; Notes buffer showing the notes: @@ -583,7 +620,9 @@ purpose of storing notes." "Major mode to use in the notes buffer when it's created. If this is nil, use `initial-major-mode'." :type '(choice (const :tag "Use `initial-major-mode'" nil) - (function :tag "Major mode" text-mode)) + (const :tag "Use `remember-initial-major-mode'" + remember-initial-major-mode) + (function :tag "Major mode" text-mode)) :version "24.4") (defcustom remember-notes-bury-on-kill t @@ -598,8 +637,6 @@ If this is nil, use `initial-major-mode'." (save-buffer)) (bury-buffer)) - - (defvar-keymap remember-notes-mode-map :doc "Keymap used in `remember-notes-mode'." "C-c C-c" #'remember-notes-save-and-bury-buffer) @@ -670,6 +707,16 @@ is non-nil, bury it and return nil; otherwise return t." nil) t)) +;; Prefix map + +(define-prefix-command 'remember-prefix-map) +;; Use with for example: +;; (keymap-global-set "C-c r" 'remember-prefix-map) + +(keymap-set remember-prefix-map "r" 'remember) +(keymap-set remember-prefix-map "c" 'remember-clipboard) +(keymap-set remember-prefix-map "n" 'remember-notes) + ;; Obsolete (defconst remember-version "2.0" "This version of remember.") commit 32ff6c9db150e5a4819cc4d7795dddfa554cad2c Author: Mauro Aranda Date: Thu Mar 13 06:48:39 2025 -0300 Recognize graphic as a type when customizing a face * lisp/cus-edit.el (custom-display): Add checkbox for graphic. (Bug#76975) diff --git a/lisp/cus-edit.el b/lisp/cus-edit.el index 5cfd2b774b7..ecfce03e490 100644 --- a/lisp/cus-edit.el +++ b/lisp/cus-edit.el @@ -3619,6 +3619,10 @@ Only match the specified window systems.") type) (checklist :inline t :offset 0 + (const :format "Graphic " + :sibling-args (:help-echo "\ +Any graphics-capable display") + graphic) (const :format "X " :sibling-args (:help-echo "\ The X11 Window System.") commit f8443dffc1fd2bc4b561b94c21cda887d2936d63 Author: Eli Zaretskii Date: Thu Mar 13 10:14:07 2025 +0200 ; * lisp/register.el (register-use-preview): Doc fix (bug#76739). diff --git a/lisp/register.el b/lisp/register.el index 373d7e54550..e802617025a 100644 --- a/lisp/register.el +++ b/lisp/register.el @@ -129,11 +129,11 @@ description of the argument. The function to use is set according to the value of `register--read-with-preview-function'.") (defcustom register-use-preview 'traditional - "Whether to show register preview when modifying registers. + "Whether register commands show preview of registers with non-nil values. When set to t, show a preview buffer with navigation and highlighting. -When set `insist', behave as with t, but allow exiting the minibuffer by +When set to `insist', behave as with t, but allow exiting the minibuffer by pressing the register name a second time. For example, press \\`a' to select register \"a\", then press \\`a' again to exit the minibuffer. commit 1528d315643d864204f327acb4ec19dd8d859de8 Author: john muhl Date: Sun Mar 9 20:40:58 2025 -0500 Simplify and improve indent rules in 'lua-ts-mode' * lisp/progmodes/lua-ts-mode.el (c-ts-common): Require it. (lua-ts-mode): Set 'c-ts-common' variables. (lua-ts--simple-indent-rules): Replace custom indent rules for tables, arguments and parameters with 'c-ts-common-baseline-indent-rule'. Improve consistency of indentation for IIFEs and nested functions. (lua-ts--variable-declaration-continuation) (lua-ts--variable-declaration-continuation-anchor): Reformat. (lua-ts--comment-first-sibling-matcher) (lua-ts--first-child-matcher, lua-ts--first-real-sibling-anchor) (lua-ts--function-definition-p, lua-ts--g-g-g-parent) (lua-ts--g-g-parent, lua-ts--nested-function-argument-matcher) (lua-ts--nested-function-block-include-matcher) (lua-ts--nested-function-block-matcher) (lua-ts--nested-function-end-argument-matcher) (lua-ts--nested-function-end-matcher) (lua-ts--nested-function-last-function-matcher) (lua-ts--top-level-function-call-matcher): Remove. * test/lisp/progmodes/lua-ts-mode-resources/indent.erts: Update tests. (Bug#76986) diff --git a/lisp/progmodes/lua-ts-mode.el b/lisp/progmodes/lua-ts-mode.el index b4025c23649..31a1a2b8aea 100644 --- a/lisp/progmodes/lua-ts-mode.el +++ b/lisp/progmodes/lua-ts-mode.el @@ -40,6 +40,7 @@ ;;; Code: +(require 'c-ts-common) (require 'comint) (require 'treesit) (treesit-declare-unavailable-functions) @@ -286,12 +287,19 @@ values of OVERRIDE." (defvar lua-ts--simple-indent-rules `((lua + ;; Handle multi-line strings and comments. ((or (and (node-is "comment") (parent-is "chunk")) lua-ts--multi-line-comment-start (parent-is "comment_content") (parent-is "string_content") (or (node-is "]]") (node-is "comment_end"))) no-indent 0) + + ;; Handle multiple "end" statements on a single line. + ((and (node-is "end") lua-ts--end-line-matcher) + standalone-parent lua-ts--end-indent-offset) + + ;; Handle tables in the arguments of a function call. ((and (n-p-gp "field" "table_constructor" "arguments") lua-ts--multi-arg-function-call-matcher lua-ts--last-arg-function-call-matcher) @@ -300,75 +308,44 @@ values of OVERRIDE." lua-ts--multi-arg-function-call-matcher lua-ts--last-arg-function-call-matcher) standalone-parent 0) - ((and (n-p-gp "field" "table_constructor" "arguments") + ((and (match "field" "table_constructor" nil 1 1) lua-ts--multi-arg-function-call-matcher) parent lua-ts-indent-offset) ((and (n-p-gp "}" "table_constructor" "arguments") lua-ts--multi-arg-function-call-matcher) parent 0) - ((or (node-is "do") - (node-is "then") - (node-is "elseif_statement") - (node-is "else_statement") - (node-is "until") - (node-is ")") - (node-is "}")) - standalone-parent 0) - ((match null "table_constructor") - standalone-parent lua-ts-indent-offset) - ((or (and (parent-is "arguments") lua-ts--first-child-matcher) - (and (parent-is "parameters") lua-ts--first-child-matcher) - (and (parent-is "table_constructor") lua-ts--first-child-matcher)) - standalone-parent lua-ts-indent-offset) - ((and (not lua-ts--comment-first-sibling-matcher) - (or (parent-is "arguments") - (parent-is "parameters") - (parent-is "table_constructor"))) - lua-ts--first-real-sibling-anchor 0) - ((or (parent-is "arguments") - (parent-is "parameters") - (parent-is "table_constructor")) - standalone-parent lua-ts-indent-offset) - ((and (n-p-gp "block" "function_definition" "parenthesized_expression") - lua-ts--nested-function-block-matcher - lua-ts--nested-function-block-include-matcher) - parent lua-ts-indent-offset) - ((and (n-p-gp "block" "function_definition" "arguments") - lua-ts--nested-function-argument-matcher) - parent lua-ts-indent-offset) - ((match "function_definition" "parenthesized_expression") - standalone-parent lua-ts-indent-offset) - ((node-is "block") standalone-parent lua-ts-indent-offset) - ((parent-is "block") parent 0) - ((and (node-is "end") lua-ts--end-line-matcher) - standalone-parent lua-ts--end-indent-offset) - ((match "end" "function_declaration") parent 0) - ((and (n-p-gp "end" "function_definition" "parenthesized_expression") - lua-ts--nested-function-end-argument-matcher) - parent 0) - ((and (n-p-gp "end" "function_definition" "parenthesized_expression") - lua-ts--nested-function-block-matcher - lua-ts--nested-function-end-matcher - lua-ts--nested-function-last-function-matcher) - parent 0) - ((and (n-p-gp "end" "function_definition" "arguments") - lua-ts--top-level-function-call-matcher) - standalone-parent 0) - ((n-p-gp "end" "function_definition" "arguments") parent 0) - ((or (match "end" "function_definition") - (node-is "end")) - standalone-parent 0) - ((n-p-gp "expression_list" "assignment_statement" "variable_declaration") - lua-ts--variable-declaration-continuation-anchor - lua-ts-indent-offset) - ((and (parent-is "binary_expression") - lua-ts--variable-declaration-continuation) + + ;; Handle multi-line concatenation and continuation. + ((or (n-p-gp "expression_list" "assignment_statement" "variable_declaration") + (and (parent-is "binary_expression") + lua-ts--variable-declaration-continuation)) lua-ts--variable-declaration-continuation-anchor lua-ts-indent-offset) + ;; `lua-ts-indent-continuation-lines' is non-nil. ((and (lambda (&rest _) lua-ts-indent-continuation-lines) (parent-is "binary_expression")) standalone-parent lua-ts-indent-offset) + ;; `lua-ts-indent-continuation-lines' is nil. ((parent-is "binary_expression") standalone-parent 0) + + ;; Handle immediately invoked function expressions. + ((or (n-p-gp "block" "function_definition" "parenthesized_expression") + (n-p-gp "block" "function_definition" "arguments")) + parent lua-ts-indent-offset) + ((or (n-p-gp "end" "function_definition" "parenthesized_expression") + (n-p-gp "end" "function_definition" "arguments")) + parent 0) + + ;; Handle basic indentation. + ((or (node-is "do") + (node-is "then") + (node-is "elseif_statement") + (node-is "else_statement") + (node-is "until") + (node-is "end") + (node-is ")")) + standalone-parent 0) + ((or (parent-is "function_declaration") (parent-is "function_definition") (parent-is "do_statement") @@ -377,10 +354,19 @@ values of OVERRIDE." (parent-is "while_statement") (parent-is "if_statement") (parent-is "else_statement") - (parent-is "elseif_statement")) + (parent-is "elseif_statement") + ;; `c-ts-common-baseline-indent-rule' will handle further + ;; siblings after the first one has been properly indented. + ;; The opening bracket occupies index 0. + (match nil "arguments" nil 1 1) + (match nil "parameters" nil 1 1) + (match "field" "table_constructor" nil 1 1)) standalone-parent lua-ts-indent-offset) + + ((parent-is "block") parent 0) ((parent-is "chunk") column-0 0) - ((parent-is "ERROR") no-indent 0)))) + ((parent-is "ERROR") no-indent 0) + c-ts-common-baseline-indent-rule))) (defun lua-ts--end-line-matcher (&rest _) "Matches if there is more than one `end' on the current line." @@ -394,27 +380,11 @@ values of OVERRIDE." "Count the number of `end's on the current line." (count-matches "end" (line-beginning-position) (line-end-position))) -(defun lua-ts--first-child-matcher (node &rest _) - "Matches if NODE is the first among its siblings." - (= (treesit-node-index node) 1)) - -(defun lua-ts--function-definition-p (node) - "Return t if NODE is a function_definition." - (equal "function_definition" (treesit-node-type node))) - (defun lua-ts--g-parent (node) "Return the grand-parent of NODE." (let ((parent (treesit-node-parent node))) (treesit-node-parent parent))) -(defun lua-ts--g-g-parent (node) - "Return the great-grand-parent of NODE." - (treesit-node-parent (lua-ts--g-parent node))) - -(defun lua-ts--g-g-g-parent (node) - "Return the great-great-grand-parent of NODE." - (treesit-node-parent (lua-ts--g-g-parent node))) - (defun lua-ts--multi-arg-function-call-matcher (_n parent &rest _) "Matches if PARENT has multiple arguments." (> (treesit-node-child-count (treesit-node-parent parent)) 3)) @@ -425,86 +395,18 @@ values of OVERRIDE." (last (1- (treesit-node-child-count g-parent t)))) (treesit-node-eq parent (seq-elt (treesit-node-children g-parent t) last)))) -(defun lua-ts--nested-function-argument-matcher (node &rest _) - "Matches if NODE is in a nested function argument." - (save-excursion - (goto-char (treesit-node-start node)) - (treesit-beginning-of-defun) - (backward-char 2) - (and (not (looking-at ")(")) - (not (equal "chunk" - (treesit-node-type - (lua-ts--g-parent (treesit-node-at (point))))))))) - -(defun lua-ts--nested-function-block-matcher (node &rest _) - "Matches if NODE is in a nested function block." - (let* ((g-g-g-parent (lua-ts--g-g-g-parent node)) - (g-g-g-type (treesit-node-type g-g-g-parent))) - (not (equal g-g-g-type "chunk")))) - -(defun lua-ts--nested-function-block-include-matcher (node _p bol &rest _) - "Matches if NODE's child at BOL is not another block." - (let* ((child (treesit-node-first-child-for-pos node bol)) - (child-type (treesit-node-type child)) - (g-g-g-type (treesit-node-type (lua-ts--g-g-g-parent node)))) - (or (equal child-type "assignment_statement") - (and (equal child-type "return_statement") - (or (equal g-g-g-type "arguments") - (and (equal g-g-g-type "expression_list") - (not (treesit-search-subtree child "function_call")))))))) - -(defun lua-ts--nested-function-end-matcher (node &rest _) - "Matches if NODE is the `end' of a nested function." - (save-excursion - (goto-char (treesit-node-start node)) - (treesit-beginning-of-defun) - (looking-at "function[[:space:]]*"))) - -(defun lua-ts--nested-function-end-argument-matcher (node &rest _) - "Matches if great-great-grandparent of NODE is arguments." - (equal "arguments" (treesit-node-type (lua-ts--g-g-g-parent node)))) - -(defun lua-ts--nested-function-last-function-matcher (_n parent &rest _) - "Matches if PARENT is the last nested function." - (let ((sparse-tree - (treesit-induce-sparse-tree parent #'lua-ts--function-definition-p))) - (= 1 (length (cadr sparse-tree))))) - -(defun lua-ts--comment-first-sibling-matcher (node &rest _) - "Matches NODE if its previous sibling is a comment." - (let ((sibling (treesit-node-prev-sibling node))) - (and (= 0 (treesit-node-index sibling t)) - (equal "comment" (treesit-node-type sibling))))) - -(defun lua-ts--top-level-function-call-matcher (node &rest _) - "Matches if NODE is within a top-level function call." - (let* ((g-g-p (lua-ts--g-g-parent node)) - (g-g-g-p (lua-ts--g-g-g-parent node))) - (and (equal "function_call" (treesit-node-type g-g-p)) - (equal "chunk" (treesit-node-type g-g-g-p))))) - -(defun lua-ts--first-real-sibling-anchor (_n parent _) - "Return the start position of the first non-comment child of PARENT." - (treesit-node-start - (seq-first - (seq-filter - (lambda (n) (not (equal "comment" (treesit-node-type n)))) - (treesit-node-children parent t))))) - (defun lua-ts--variable-declaration-continuation (node &rest _) "Matches if NODE is part of a multi-line variable declaration." - (treesit-parent-until node - (lambda (p) - (equal "variable_declaration" - (treesit-node-type p))))) + (treesit-parent-until node (lambda (p) + (equal "variable_declaration" + (treesit-node-type p))))) (defun lua-ts--variable-declaration-continuation-anchor (node &rest _) "Return the start position of the variable declaration for NODE." (save-excursion (goto-char (treesit-node-start (lua-ts--variable-declaration-continuation node))) - (when (looking-back (rx bol (* whitespace)) - (line-beginning-position)) + (when (looking-back (rx bol (* whitespace)) (line-beginning-position)) (point)))) (defun lua-ts--multi-line-comment-start (node &rest _) @@ -783,6 +685,8 @@ Calls REPORT-FN directly." variable))) ;; Indent. + (setq-local c-ts-common-indent-offset 'lua-ts-indent-offset) + (setq-local c-ts-common-list-indent-style 'simple) (setq-local treesit-simple-indent-rules lua-ts--simple-indent-rules) ;; Navigation. diff --git a/test/lisp/progmodes/lua-ts-mode-resources/indent.erts b/test/lisp/progmodes/lua-ts-mode-resources/indent.erts index b0ece4cc261..575e0e2cbf0 100644 --- a/test/lisp/progmodes/lua-ts-mode-resources/indent.erts +++ b/test/lisp/progmodes/lua-ts-mode-resources/indent.erts @@ -1,7 +1,7 @@ Code: (lambda () - (setq indent-tabs-mode nil) (setq lua-ts-indent-offset 2) + (setq indent-tabs-mode nil) (lua-ts-mode) (indent-region (point-min) (point-max))) @@ -15,24 +15,51 @@ print(1) print(2) =-=-= -Name: Function Indent +Name: Function Indent 1 =-= function f1(n) print(n) return n + 1 end +=-= +function f1(n) + print(n) + return n + 1 +end +=-=-= + +Name: Function Indent 2 +=-= local function f2(n) print(n) return n * 2 end +=-= +local function f2(n) + print(n) + return n * 2 +end +=-=-= +Name: Function Indent 3 + +=-= local f3 = function(n) print(n) return n / 3 end +=-= +local f3 = function(n) + print(n) + return n / 3 +end +=-=-= +Name: Function Indent 4 + +=-= function f4(...) local f = function (...) if ok @@ -42,7 +69,21 @@ end end return f end +=-= +function f4(...) + local f = function (...) + if ok + then print(1) + else print(0) + end + end + return f +end +=-=-= + +Name: Function Indent 5 +=-= function f5(...) local f = function (...) if ok @@ -54,51 +95,7 @@ end end return f end - -function f6(...) -local f = function (...) -if ok then -print(1) -else -print(0) -end -end -return f -end - -f6(function() -print'ok' -end) - -;(function () - return true - end)() =-= -function f1(n) - print(n) - return n + 1 -end - -local function f2(n) - print(n) - return n * 2 -end - -local f3 = function(n) - print(n) - return n / 3 -end - -function f4(...) - local f = function (...) - if ok - then print(1) - else print(0) - end - end - return f -end - function f5(...) local f = function (...) if ok @@ -110,7 +107,22 @@ function f5(...) end return f end +=-=-= + +Name: Function Indent 6 +=-= +function f6(...) +local f = function (...) +if ok then +print(1) +else +print(0) +end +end +return f +end +=-= function f6(...) local f = function (...) if ok then @@ -121,17 +133,33 @@ function f6(...) end return f end +=-=-= + +Name: Function Indent 7 -f6(function() - print'ok' +=-= +f7(function() +print'ok' end) +=-= +f7(function() + print'ok' + end) +=-=-= + +Name: Function Indent 8 +=-= ;(function () - return true -end)() + return true + end)() +=-= +;(function () + return true + end)() =-=-= -Name: Conditional Indent +Name: Conditional Indent 1 =-= if true then @@ -144,7 +172,22 @@ else print(nil) return 0 end +=-= +if true then + print(true) + return 1 +elseif false then + print(false) + return -1 +else + print(nil) + return 0 +end +=-=-= +Name: Conditional Indent 2 + +=-= if true then print(true) @@ -157,25 +200,7 @@ if true print(nil) return 0 end - -if true - then return 1 - elseif false - then return -1 - else return 0 -end =-= -if true then - print(true) - return 1 -elseif false then - print(false) - return -1 -else - print(nil) - return 0 -end - if true then print(true) @@ -188,7 +213,18 @@ else print(nil) return 0 end +=-=-= +Name: Conditional Indent 3 + +=-= +if true + then return 1 + elseif false + then return -1 + else return 0 +end +=-= if true then return 1 elseif false @@ -197,39 +233,93 @@ else return 0 end =-=-= -Name: Loop Indent +Name: Loop Indent 1 =-= for k,v in pairs({}) do print(k) print(v) end +=-= +for k,v in pairs({}) do + print(k) + print(v) +end +=-=-= +Name: Loop Indent 2 + +=-= for i=1,10 do print(i) end +=-= +for i=1,10 +do print(i) +end +=-=-= +Name: Loop Indent 3 + +=-= while n < 10 do n = n + 1 print(n) end +=-= +while n < 10 do + n = n + 1 + print(n) +end +=-=-= + +Name: Loop Indent 4 +=-= while n < 10 do n = n + 1 print(n) end +=-= +while n < 10 +do + n = n + 1 + print(n) +end +=-=-= + +Name: Loop Indent 5 +=-= for i=0,9 do repeat n = n+1 until n > 99 end +=-= +for i=0,9 do + repeat n = n+1 + until n > 99 +end +=-=-= + +Name: Loop Indent 6 +=-= repeat z = z * 2 print(z) until z > 12 +=-= +repeat + z = z * 2 + print(z) +until z > 12 +=-=-= + +Name: Loop Indent 7 +=-= for i,x in ipairs(t) do while i < 9 do @@ -243,42 +333,7 @@ until z > 12 end print(t[i]) end - -do -local a = b -print(a + 1) -end =-= -for k,v in pairs({}) do - print(k) - print(v) -end - -for i=1,10 -do print(i) -end - -while n < 10 do - n = n + 1 - print(n) -end - -while n < 10 -do - n = n + 1 - print(n) -end - -for i=0,9 do - repeat n = n+1 - until n > 99 -end - -repeat - z = z * 2 - print(z) -until z > 12 - for i,x in ipairs(t) do while i < 9 do @@ -292,37 +347,54 @@ for i,x in ipairs(t) do end print(t[i]) end +=-=-= + +Name: Loop Indent 8 +=-= +do +local a = b +print(a + 1) +end +=-= do local a = b print(a + 1) end =-=-= -Name: Bracket Indent +Name: Bracket Indent 1 =-= fn( ) - -tb={ - } =-= fn( ) +=-=-= +Name: Bracket Indent 2 + +=-= +tb={ + } +=-= tb={ } =-=-= -Name: Multi-line String Indent +Name: Multi-line String Indent 1 =-= local s = [[ Multi-line string content ]] +=-=-= +Name: Multi-line String Indent 2 + +=-= function f() local str = [[ multi-line @@ -331,11 +403,6 @@ function f() return true end =-= -local s = [[ - Multi-line - string content - ]] - function f() local str = [[ multi-line @@ -345,31 +412,18 @@ function f() end =-=-= -Name: Multi-line Comment Indent +Name: Multi-line Comment Indent 1 =-= --[[ Multi-line comment content ]] +=-=-= -function f() ---[[ -multi-line - comment - ]] - return true -end +Name: Multi-line Comment Indent 2 - --[[ -Long comment. - ]] =-= ---[[ - Multi-line - comment content - ]] - function f() --[[ multi-line @@ -377,143 +431,191 @@ multi-line ]] return true end +=-=-= + +Name: Multi-line Comment Indent 3 +=-= --[[ Long comment. ]] =-=-= -Name: Comment Indent +Name: Comment Indent 1 =-= local fn1 = function (a, b) -- comment return a + b end +=-= +local fn1 = function (a, b) + -- comment + return a + b +end +=-=-= + +Name: Comment Indent 2 +=-= local tb1 = { first = 1, -- comment second = 2, } - -local tb9 = { one = 1, --- comment - two = 2 } =-= -local fn1 = function (a, b) - -- comment - return a + b -end - local tb1 = { first = 1, -- comment second = 2, } - -local tb9 = { one = 1, - -- comment - two = 2 } =-=-= -Name: Argument Indent - -=-= - h( - "string", - 1000 - ) - -local p = h( -"string", - 1000 -) - -fn(1, -2, - 3) - -fn( 1, 2, -3, 4 ) - -f({ -x = 1, -y = 2, -z = 3, -}) - -f({ x = 1, -y = 2, -z = 3, }) - -Test({ -a=1 -}) +Name: Comment Indent 3 -Test({ -a = 1, -b = 2, -}, -nil) +=-= +local tb9 = { one = 1, +-- comment + two = 2 } +=-= +local tb9 = { one = 1, + -- comment + two = 2 } +=-=-= -Test(nil, { - a = 1, - b = 2, - }) +Name: Argument Indent 1 -fn( -- comment - 1, - 2) +=-= + h( + "string", + 1000 + ) =-= h( "string", 1000 ) +=-=-= +Name: Argument Indent 2 + +=-= +local p = h( +"string", + 1000 +) +=-= local p = h( "string", 1000 ) +=-=-= +Name: Argument Indent 3 + +=-= +fn(1, +2, + 3) +=-= fn(1, 2, 3) +=-=-= + +Name: Argument Indent 4 +=-= +fn( 1, 2, +3, 4 ) +=-= fn( 1, 2, 3, 4 ) +=-=-= + +Name: Argument Indent 5 +=-= +f({ +x = 1, +y = 2, +z = 3, +}) +=-= f({ x = 1, y = 2, z = 3, }) +=-=-= +Name: Argument Indent 6 + +=-= +f({ x = 1, +y = 2, +z = 3, }) +=-= f({ x = 1, y = 2, z = 3, }) +=-=-= + +Name: Argument Indent 7 +=-= +Test({ +a=1 +}) +=-= Test({ a=1 }) +=-=-= +Name: Argument Indent 8 + +=-= +Test({ +a = 1, +b = 2, +}, +nil) +=-= Test({ a = 1, b = 2, }, nil) +=-=-= + +Name: Argument Indent 9 +=-= +Test(nil, { + a = 1, + b = 2, + }) +=-= Test(nil, { a = 1, b = 2, }) +=-=-= + +Name: Argument Indent 10 +=-= +fn( -- comment + 1, + 2) +=-= fn( -- comment 1, 2) =-=-= -Name: Parameter Indent +Name: Parameter Indent 1 =-= function f1( @@ -522,19 +624,6 @@ b ) print(a,b) end - -local function f2(a, - b) -print(a,b) -end - -local f3 = function( a, b, - c, d ) -print(a,b,c,d) -end - -local f4 = function(-- comment -a, b, c) =-= function f1( a, @@ -542,22 +631,47 @@ function f1( ) print(a,b) end +=-=-= + +Name: Parameter Indent 2 +=-= +local function f2(a, + b) +print(a,b) +end +=-= local function f2(a, b) print(a,b) end +=-=-= + +Name: Parameter Indent 3 +=-= +local f3 = function( a, b, + c, d ) +print(a,b,c,d) +end +=-= local f3 = function( a, b, c, d ) print(a,b,c,d) end +=-=-= + +Name: Parameter Indent 4 +=-= +local f4 = function(-- comment +a, b, c) +=-= local f4 = function(-- comment a, b, c) =-=-= -Name: Table Indent +Name: Table Indent 1 =-= local Other = { @@ -574,16 +688,6 @@ local Other = { left={Goto=true}, right={Goto=true}} } - -local Other = { -a = 1, - b = 2, - c = 3, -} - -local a = { -- hello world! - b = 10 -} =-= local Other = { First={up={Step=true,Jump=true}, @@ -599,31 +703,77 @@ local Other = { left={Goto=true}, right={Goto=true}} } +=-=-= + +Name: Table Indent 2 +=-= +local Other = { +a = 1, + b = 2, + c = 3, +} +=-= local Other = { a = 1, b = 2, c = 3, } +=-=-= +Name: Table Indent 3 + +=-= +local a = { -- hello world! + b = 10 +} +=-= local a = { -- hello world! b = 10 } =-=-= -Name: Continuation Indent +Name: Continuation Indent 1 =-= local very_long_variable_name = "ok".. "ok" +=-= +local very_long_variable_name = + "ok".. + "ok" +=-=-= + +Name: Continuation Indent 2 + +=-= local n = a + b * c / 1 +=-= +local n = a + + b * + c / + 1 +=-=-= + +Name: Continuation Indent 3 + +=-= local x = "A".. "B" .."C" +=-= +local x = "A".. + "B" + .."C" +=-=-= + +Name: Continuation Indent 4 + +=-= if a and b and c then @@ -638,16 +788,6 @@ elseif a or c then end =-= -local very_long_variable_name = - "ok".. - "ok" -local n = a + - b * - c / - 1 -local x = "A".. - "B" - .."C" if a and b and c then @@ -665,12 +805,12 @@ end Code: (lambda () - (setq indent-tabs-mode nil) (setq lua-ts-indent-offset 4) (lua-ts-mode) + (setq indent-tabs-mode nil) (indent-region (point-min) (point-max))) -Name: End Indent +Name: End Indent 1 =-= function f(x) @@ -682,14 +822,6 @@ function f(x) end end end end return {x,y} or {math.random(),math.random()} end - -for y=1,x.y do - for x=1,x.z do - if x.y and x.z then - if y <= x then - y = y + 1 - end - end end end =-= function f(x) for y=1,x.y do @@ -700,7 +832,19 @@ function f(x) end end end end return {x,y} or {math.random(),math.random()} end +=-=-= +Name: End Indent 2 + +=-= +for y=1,x.y do + for x=1,x.z do + if x.y and x.z then + if y <= x then + y = y + 1 + end + end end end +=-= for y=1,x.y do for x=1,x.z do if x.y and x.z then @@ -710,30 +854,78 @@ for y=1,x.y do end end end =-=-= -Name: Nested Function Indent +Name: Nested Function Indent 1 +=-= +function a(...) +return (function (x) +return x +end)(foo(...)) +end =-= function a(...) return (function (x) return x end)(foo(...)) end +=-=-= +Name: Nested Function Indent 2 + +=-= +function b(n) +local x = 1 +return function (i) +return function (...) +return (function (n, ...) +return function (f, ...) +return (function (...) +if ... and x < 9 then +x = x + 1 +return ... +end end)(n(f, ...)) +end, ... +end)(i(...)) +end end end +=-= function b(n) local x = 1 return function (i) return function (...) return (function (n, ...) - return function (f, ...) - return (function (...) - if ... and x < 9 then - x = x + 1 - return ... - end end)(n(f, ...)) - end, ... - end)(i(...)) + return function (f, ...) + return (function (...) + if ... and x < 9 then + x = x + 1 + return ... + end end)(n(f, ...)) + end, ... + end)(i(...)) end end end +=-=-= +Name: Nested Function Indent 3 + +=-= +function c(f) +local f1 = function (...) +if nil ~= ... then +return f(...) +end +end +return function (i) +return function (...) +local fn = function (n, ...) +local x = function (f, ...) +return f1(n(f, ...)) +end +return x +end +return fn(i(...)) +end +end +end +=-= function c(f) local f1 = function (...) if nil ~= ... then @@ -752,7 +944,29 @@ function c(f) end end end +=-=-= +Name: Nested Function Indent 4 + +=-= +function d(f) +local f1 = function (c, f, ...) +if ... then +if f(...) then +return ... +else +return c(f, ...) +end end end +return function (i) +return function (...) +return (function (n, ...) +local function j (f, ...) +return f1(j, f, n(f, ...)) +end +return j, ... +end)(i(...)) +end end end +=-= function d(f) local f1 = function (c, f, ...) if ... then @@ -764,13 +978,57 @@ function d(f) return function (i) return function (...) return (function (n, ...) - local function j (f, ...) - return f1(j, f, n(f, ...)) - end - return j, ... - end)(i(...)) + local function j (f, ...) + return f1(j, f, n(f, ...)) + end + return j, ... + end)(i(...)) end end end +=-=-= +Name: Nested Function Indent 5 + +=-= +function e (n, t) +return function (i) +return function (...) +return ( +function (n, ...) +local x, y, z = 0, {} +return (function (f, ...) +return (function (i, ...) return i(i, ...) end)( +function (i, ...) +return f(function (x, ...) +return i(i, ...)(x, ...) +end, ...) +end) +end)(function (j) +return function(f, ...) +return (function (c, f, ...) +if ... then +if n+1 == x then +local y1, x1 = y, x +y, x = {}, 0 +return (function (...) +z = ... +return ... +end)(t(y1-1, x1-1, ...)) +else +x = x - 1 +return c(f, +(function (...) +z = ... +return ... +end)(t(y, x, ...))) +end +elseif x ~= 0 then +x = 0 +return z, y +end end)(j, f, n(f, ...)) +end end), ... +end)(i(...)) +end end end +=-= function e (n, t) return function (i) return function (...) @@ -778,46 +1036,46 @@ function e (n, t) function (n, ...) local x, y, z = 0, {} return (function (f, ...) - return (function (i, ...) return i(i, ...) end)( - function (i, ...) - return f(function (x, ...) - return i(i, ...)(x, ...) - end, ...) - end) - end)(function (j) - return function(f, ...) - return (function (c, f, ...) - if ... then - if n+1 == x then - local y1, x1 = y, x - y, x = {}, 0 - return (function (...) - z = ... - return ... - end)(t(y1-1, x1-1, ...)) - else - x = x - 1 - return c(f, - (function (...) - z = ... - return ... - end)(t(y, x, ...))) - end - elseif x ~= 0 then - x = 0 - return z, y - end end)(j, f, n(f, ...)) - end end), ... + return (function (i, ...) return i(i, ...) end)( + function (i, ...) + return f(function (x, ...) + return i(i, ...)(x, ...) + end, ...) + end) + end)(function (j) + return function(f, ...) + return (function (c, f, ...) + if ... then + if n+1 == x then + local y1, x1 = y, x + y, x = {}, 0 + return (function (...) + z = ... + return ... + end)(t(y1-1, x1-1, ...)) + else + x = x - 1 + return c(f, + (function (...) + z = ... + return ... + end)(t(y, x, ...))) + end + elseif x ~= 0 then + x = 0 + return z, y + end end)(j, f, n(f, ...)) + end end), ... end)(i(...)) end end end =-=-= Code: (lambda () - (setq indent-tabs-mode nil) (setq lua-ts-indent-continuation-lines nil) (setq lua-ts-indent-offset 2) (lua-ts-mode) + (setq indent-tabs-mode nil) (indent-region (point-min) (point-max))) Name: Unaligned Continuation Indent commit b51fb2e107a4b3b17f5ced188247479cff0a3c92 Author: Stefan Kangas Date: Thu Mar 13 08:13:24 2025 +0100 Fix loading follow.el * lisp/follow.el (follow-mode-prefix-key): Avoid changing follow-mode-map before it is defined. (Bug#76977) * test/lisp/follow-tests.el: New file. diff --git a/lisp/follow.el b/lisp/follow.el index 91a4bec619b..ddf72845eed 100644 --- a/lisp/follow.el +++ b/lisp/follow.el @@ -234,8 +234,9 @@ After that, changing the prefix key requires manipulating keymaps." :type 'string :set (lambda (symbol value) (defvar follow-mode-map) (defvar follow-mode-submap) - (keymap-unset follow-mode-map (symbol-value symbol)) - (keymap-set follow-mode-map value follow-mode-submap) + (when (boundp 'follow-mode-map) + (keymap-unset follow-mode-map (symbol-value symbol)) + (keymap-set follow-mode-map value follow-mode-submap)) (set-default symbol value)) :group 'follow :version "31.1") diff --git a/test/lisp/follow-tests.el b/test/lisp/follow-tests.el new file mode 100644 index 00000000000..29bda77873b --- /dev/null +++ b/test/lisp/follow-tests.el @@ -0,0 +1,32 @@ +;;; follow-tests.el --- Tests for follow.el -*- 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 'follow) + +(ert-deftest follow-tests-do-nothing-test () + ;; Placeholder test to verify that loading `follow' succeeds. + ;; Suppresses an ERT warning due to the absence of tests. + ;; + ;; Remove this test if real tests are added later. + ) + +(provide 'follow-tests) +;;; follow-tests.el ends here commit f729828bcfbca8e972467ace85dd32744e4dd6de Author: Jeremy Bryant Date: Sun Mar 9 22:25:03 2025 +0000 ; Add texinfo reference to GNU Coding Standards. * doc/emacs/trouble.texi (Coding Standards): Add texinfo reference to GNU Coding Standards manual. (Bug#76901) diff --git a/doc/emacs/trouble.texi b/doc/emacs/trouble.texi index 2211369b121..45f15c7dd0d 100644 --- a/doc/emacs/trouble.texi +++ b/doc/emacs/trouble.texi @@ -1494,9 +1494,10 @@ the Emacs Lisp Reference Manual @subsection Coding Standards @cindex coding standards for Emacs submissions -Contributed code should follow the GNU Coding Standards -@url{https://www.gnu.org/prep/standards/}. This may also be available -in info on your system. +Contributed code should follow the GNU Coding Standards. This manual +is available online at @url{https://www.gnu.org/prep/standards/}. It +may also be available locally in Info on your system, see @pxref{Top,,, +standards, GNU Coding Standards}. If it doesn't, we'll need to find someone to fix the code before we can use it. commit ae33aad7f582864a8dbb0fee10f891fd67abdbe3 Author: Daniel Mendler Date: Sat Mar 8 09:23:53 2025 +0100 window-tool-bar: Use `static-if' from Compat 30 * lisp/window-tool-bar.el (window-tool-bar--static-if): Remove macro. (window-tool-bar--ignored-event-types): Use `static-if' from Compat instead. (Bug#76858) diff --git a/lisp/window-tool-bar.el b/lisp/window-tool-bar.el index b8f84bd2da7..ace01885134 100644 --- a/lisp/window-tool-bar.el +++ b/lisp/window-tool-bar.el @@ -7,7 +7,7 @@ ;; Version: 0.3 ;; Keywords: mouse ;; URL: http://github.com/chaosemer/window-tool-bar -;; Package-Requires: ((emacs "27.1") (compat "29.1")) +;; Package-Requires: ((emacs "27.1") (compat "30")) ;; This is a GNU ELPA :core package. Avoid adding functionality that ;; is not available in the version of Emacs recorded above or any of @@ -385,26 +385,13 @@ MENU-ITEM is a menu item to convert. See info node `(elisp)Tool Bar'." (interactive) nil) -;; static-if was added in Emacs 30, but this packages supports earlier -;; versions. -(defmacro window-tool-bar--static-if (condition then-form &rest else-forms) - "A conditional compilation macro. -Evaluate CONDITION at macro-expansion time. If it is non-nil, -expand the macro to THEN-FORM. Otherwise expand it to ELSE-FORMS -enclosed in a `progn' form. ELSE-FORMS may be empty." - (declare (indent 2) - (debug (sexp sexp &rest sexp))) - (if (eval condition lexical-binding) - then-form - (cons 'progn else-forms))) - (defvar window-tool-bar--ignored-event-types (let ((list (append '(mouse-movement pinch wheel-down wheel-up wheel-left wheel-right) ;; Prior to emacs 30, wheel events could also surface as ;; mouse- buttons. - (window-tool-bar--static-if (version< emacs-version "30") + (static-if (< emacs-major-version 30) (list mouse-wheel-down-event mouse-wheel-up-event mouse-wheel-left-event mouse-wheel-right-event commit 99d034cfd3fd807570b14a56413fc61e2c964c65 Author: Stefan Kangas Date: Wed Mar 12 09:15:53 2025 +0100 ; Fix mistake in defvar-keymap conversion A mix of `keymap-set` and `define-key` confused the automated conversion. Problem reported by Juri Linkov . diff --git a/lisp/outline.el b/lisp/outline.el index 0e5aff724aa..1a1c8705ee2 100644 --- a/lisp/outline.el +++ b/lisp/outline.el @@ -74,30 +74,30 @@ appropriately. When the argument LOOKING-AT is non-nil, it should imitate the function `looking-at'.") (defvar-keymap outline-mode-prefix-map - "@" #'outline-mark-subtree - "C-n" #'outline-next-visible-heading - "C-p" #'outline-previous-visible-heading - "C-i" #'outline-show-children - "C-s" #'outline-show-subtree - "C-d" #'outline-hide-subtree - "C-u" #'outline-up-heading - "C-f" #'outline-forward-same-level - "C-b" #'outline-backward-same-level - "C-t" #'outline-hide-body - "C-a" #'outline-show-all - "C-c" #'outline-hide-entry - "C-e" #'outline-show-entry - "C-l" #'outline-hide-leaves - "C-k" #'outline-show-branches - "C-q" #'outline-hide-sublevels - "C-o" #'outline-hide-other - "C-^" #'outline-move-subtree-up - "C-v" #'outline-move-subtree-down - "/ SPC s" #'outline-show-by-heading-regexp - "/ SPC h" #'outline-hide-by-heading-regexp - "C-<" #'outline-promote - "C->" #'outline-demote - "RET" #'outline-insert-heading) + "@" #'outline-mark-subtree + "C-n" #'outline-next-visible-heading + "C-p" #'outline-previous-visible-heading + "C-i" #'outline-show-children + "C-s" #'outline-show-subtree + "C-d" #'outline-hide-subtree + "C-u" #'outline-up-heading + "C-f" #'outline-forward-same-level + "C-b" #'outline-backward-same-level + "C-t" #'outline-hide-body + "C-a" #'outline-show-all + "C-c" #'outline-hide-entry + "C-e" #'outline-show-entry + "C-l" #'outline-hide-leaves + "C-k" #'outline-show-branches + "C-q" #'outline-hide-sublevels + "C-o" #'outline-hide-other + "C-^" #'outline-move-subtree-up + "C-v" #'outline-move-subtree-down + "/ s" #'outline-show-by-heading-regexp + "/ h" #'outline-hide-by-heading-regexp + "C-<" #'outline-promote + "C->" #'outline-demote + "RET" #'outline-insert-heading) (defvar outline-mode-menu-bar-map (let ((map (make-sparse-keymap))) commit 13a043fec95f9f6b9721b3c6ff0a3248b14d40cc Author: Michael Albinus Date: Wed Mar 12 20:56:24 2025 +0100 Tramp: Don't offer non-existing containers in completion * doc/misc/tramp.texi (File name completion): Explain "completion-use-cache" property. * lisp/net/tramp-cache.el (tramp-get-method-parameter): Declare. (tramp-get-hash-table): Mark connection properties. (tramp-dump-connection-properties): Remove empty lists. (tramp-parse-connection-properties): Take connection property "completion-use-cache" into account. (Bug#76950) * lisp/net/tramp-container.el (tramp-methods) : Add `tramp-completion-use-cache' argument. diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi index 0f9ffced90c..81feb56ec31 100644 --- a/doc/misc/tramp.texi +++ b/doc/misc/tramp.texi @@ -3798,7 +3798,18 @@ completion lists. If you want to suppress this completion because there are invalid entries in the persistency file, for example if the host configuration changes often, or if you plug your laptop to different networks frequently, you can set the user option -@code{tramp-completion-use-cache} to @code{nil}. +@code{tramp-completion-use-cache} to @code{nil}. This is set per +default for all container-based methods, like @option{docker} or +@option{podman}. If you want to suppress this for other connections, +you can use the connection property @t{"completion-use-cache"}, +@xref{Predefined connection information}. Example: + +@lisp +@group +(add-to-list 'tramp-connection-properties + (list "^/sshfs:" "completion-use-cache" nil)) +@end group +@end lisp After remote host name completion comes completion of file names on the remote host. It works the same as with local host file completion diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el index 2694b8f490a..4ff7d649b42 100644 --- a/lisp/net/tramp-cache.el +++ b/lisp/net/tramp-cache.el @@ -73,6 +73,9 @@ ;; `tramp-persistency-file-name', although being connection ;; properties related to a `tramp-file-name' structure. ;; +;; - Properties retrieved from `tramp-connection-properties' are not +;; saved in the file `tramp-persistency-file-name'. +;; ;; - Reusable properties, which should not be saved, are kept in the ;; process key retrieved by `tramp-get-process' (the main connection ;; process). Other processes could reuse these properties, avoiding @@ -86,6 +89,8 @@ (require 'tramp-compat) (require 'time-stamp) +(declare-function tramp-get-method-parameter "tramp") + ;;; -- Cache -- ;;;###tramp-autoload @@ -136,17 +141,20 @@ If it doesn't exist yet, it is created and initialized with matching entries of `tramp-connection-properties'. If KEY is `tramp-cache-undefined', don't create anything, and return nil." ;; (declare (tramp-suppress-trace t)) - (unless (eq key tramp-cache-undefined) - (or (gethash key tramp-cache-data) - (let ((hash - (puthash key (make-hash-table :test #'equal) tramp-cache-data))) - (when (tramp-file-name-p key) - (dolist (elt tramp-connection-properties) - (when (string-match-p - (or (nth 0 elt) "") - (tramp-make-tramp-file-name key 'noloc)) - (tramp-set-connection-property key (nth 1 elt) (nth 2 elt))))) - hash)))) + (let ((tramp-verbose 0)) + (unless (eq key tramp-cache-undefined) + (or (gethash key tramp-cache-data) + (let ((hash + (puthash key (make-hash-table :test #'equal) tramp-cache-data))) + (when (tramp-file-name-p key) + (dolist (elt tramp-connection-properties) + (when (string-match-p + (or (nth 0 elt) "") + (tramp-make-tramp-file-name key 'noloc)) + ;; Mark it as taken from `tramp-connection-properties'. + (tramp-set-connection-property + key (propertize (nth 1 elt) 'tramp-default t) (nth 2 elt))))) + hash))))) ;; We cannot use the `declare' form for `tramp-suppress-trace' in ;; autoloaded functions, because the tramp-loaddefs.el generation @@ -596,9 +604,14 @@ PROPERTIES is a list of file properties (strings)." (not (tramp-file-name-localname key)) (not (gethash "login-as" value)) (not (gethash "started" value))) - (dolist (k (hash-table-keys value)) - (when (string-prefix-p " " k) - (remhash k value))) + (progn + (dolist (k (hash-table-keys value)) + ;; Suppress ephemeral properties. + (when (or (string-prefix-p " " k) + (get-text-property 0 'tramp-default k)) + (remhash k value))) + (unless (hash-table-keys value) + (remhash key cache))) (remhash key cache))) cache) ;; Dump it. @@ -635,15 +648,17 @@ your laptop to different networks frequently." "Return a list of (user host) tuples allowed to access for METHOD. This function is added always in `tramp-get-completion-function' for all methods. Resulting data are derived from connection history." - (and tramp-completion-use-cache - (mapcar - (lambda (key) - (and (tramp-file-name-p key) - (string-equal method (tramp-file-name-method key)) - (not (tramp-file-name-localname key)) - (list (tramp-file-name-user key) - (tramp-file-name-host key)))) - (hash-table-keys tramp-cache-data)))) + (mapcar + (lambda (key) + (let ((tramp-verbose 0)) + (and (tramp-file-name-p key) + (string-equal method (tramp-file-name-method key)) + (not (tramp-file-name-localname key)) + (tramp-get-method-parameter + key 'tramp-completion-use-cache tramp-completion-use-cache) + (list (tramp-file-name-user key) + (tramp-file-name-host key))))) + (hash-table-keys tramp-cache-data))) ;; When "emacs -Q" has been called, both variables are nil. We do not ;; load the persistency file then, in order to have a clean test environment. diff --git a/lisp/net/tramp-container.el b/lisp/net/tramp-container.el index 0f1ce71caa3..8429208b44b 100644 --- a/lisp/net/tramp-container.el +++ b/lisp/net/tramp-container.el @@ -556,7 +556,8 @@ see its function help for a description of the format." (tramp-direct-async (,tramp-default-remote-shell "-c")) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) - (tramp-remote-shell-args ("-i" "-c")))) + (tramp-remote-shell-args ("-i" "-c")) + (tramp-completion-use-cache nil))) (add-to-list 'tramp-methods `(,tramp-dockercp-method @@ -573,7 +574,8 @@ see its function help for a description of the format." (tramp-copy-program ,tramp-docker-program) (tramp-copy-args (("cp"))) (tramp-copy-file-name (("%h" ":") ("%f"))) - (tramp-copy-recursive t))) + (tramp-copy-recursive t) + (tramp-completion-use-cache nil))) (add-to-list 'tramp-methods `(,tramp-podman-method @@ -586,7 +588,8 @@ see its function help for a description of the format." (tramp-direct-async (,tramp-default-remote-shell "-c")) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) - (tramp-remote-shell-args ("-i" "-c")))) + (tramp-remote-shell-args ("-i" "-c")) + (tramp-completion-use-cache nil))) (add-to-list 'tramp-methods `(,tramp-podmancp-method @@ -603,7 +606,8 @@ see its function help for a description of the format." (tramp-copy-program ,tramp-podman-program) (tramp-copy-args (("cp"))) (tramp-copy-file-name (("%h" ":") ("%f"))) - (tramp-copy-recursive t))) + (tramp-copy-recursive t) + (tramp-completion-use-cache nil))) (add-to-list 'tramp-methods `(,tramp-kubernetes-method @@ -618,7 +622,8 @@ see its function help for a description of the format." (tramp-direct-async (,tramp-default-remote-shell "-c")) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) - (tramp-remote-shell-args ("-i" "-c")))) + (tramp-remote-shell-args ("-i" "-c")) + (tramp-completion-use-cache nil))) (add-to-list 'tramp-completion-multi-hop-methods tramp-docker-method) (add-to-list 'tramp-completion-multi-hop-methods tramp-podman-method) @@ -674,7 +679,8 @@ see its function help for a description of the format." (tramp-direct-async (,tramp-default-remote-shell "-c")) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) - (tramp-remote-shell-args ("-c")))) + (tramp-remote-shell-args ("-c")) + (tramp-completion-use-cache nil))) (add-to-list 'tramp-default-host-alist `(,tramp-toolbox-method nil "")) (add-to-list 'tramp-completion-multi-hop-methods tramp-toolbox-method) @@ -695,7 +701,8 @@ see its function help for a description of the format." ;(tramp-direct-async (,tramp-default-remote-shell "-c")) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) - (tramp-remote-shell-args ("-c")))) + (tramp-remote-shell-args ("-c")) + (tramp-completion-use-cache nil))) (add-to-list 'tramp-completion-multi-hop-methods tramp-distrobox-method) @@ -719,7 +726,8 @@ see its function help for a description of the format." (tramp-direct-async (,tramp-default-remote-shell "-c")) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) - (tramp-remote-shell-args ("-c")))) + (tramp-remote-shell-args ("-c")) + (tramp-completion-use-cache nil))) (add-to-list 'tramp-completion-multi-hop-methods tramp-flatpak-method) @@ -750,7 +758,8 @@ see its function help for a description of the format." ("%h"))) ; Needed for multi-hop check. (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) - (tramp-remote-shell-args ("-c")))) + (tramp-remote-shell-args ("-c")) + (tramp-completion-use-cache nil))) (add-to-list 'tramp-completion-multi-hop-methods tramp-apptainer-method) @@ -771,7 +780,8 @@ see its function help for a description of the format." ("%h"))) (tramp-remote-shell ,tramp-default-remote-shell) (tramp-remote-shell-login ("-l")) - (tramp-remote-shell-args ("-i" "-c")))) + (tramp-remote-shell-args ("-i" "-c")) + (tramp-completion-use-cache nil))) (add-to-list 'tramp-default-host-alist `(,tramp-nspawn-method nil ".host")) (add-to-list 'tramp-completion-multi-hop-methods tramp-nspawn-method) commit 85c00405b9e349eeabbdb305e5f8da41600d0b89 Author: Arash Esbati Date: Wed Mar 12 18:48:22 2025 +0100 ; Improve `reftex-toc-help' * lisp/textmodes/reftex-toc.el (reftex-toc-help): Remove unnecessary spaces. Use \` for key sequence. diff --git a/lisp/textmodes/reftex-toc.el b/lisp/textmodes/reftex-toc.el index 24e4864be8b..d8d09da5ed0 100644 --- a/lisp/textmodes/reftex-toc.el +++ b/lisp/textmodes/reftex-toc.el @@ -162,14 +162,14 @@ Here are all local bindings. \\`C-c >' Display Index. With prefix arg, restrict index to current section. \\`q' / \\`k' Hide/Kill *toc* buffer, return to position of reftex-toc command. \\`l' \\`i' \\`c' \\`F' Toggle display of [l]abels, [i]ndex, [c]ontext, [F]ile borders. -\\`t' Change maximum toc depth (e.g. `3 t' hides levels greater than 3). +\\`t' Change maximum toc depth (e.g., \\`3 t' hides levels greater than 3). \\`f' / \\`g' Toggle follow mode / Refresh *toc* buffer. \\`a' / \\`d' Toggle auto recenter / Toggle dedicated frame -\\`r' / \\`C-u r' Reparse the LaTeX document / Reparse entire LaTeX document. +\\`r' / \\`C-u r' Reparse the LaTeX document / Reparse entire LaTeX document. \\`.' In other window, show position from where `reftex-toc' was called. \\`M-%' Global search and replace to rename label at point. \\`x' Switch to TOC of external document (with LaTeX package `xr'). -\\`z' Jump to a specific section (e.g. \\`3 z' goes to section 3).") +\\`z' Jump to a specific section (e.g., \\`3 z' goes to section 3).") (defvar reftex--rebuilding-toc nil) commit 6ab65281c54a1fcef90786f9d50142e3427781fb Author: Stephen Gildea Date: Wed Mar 12 07:02:44 2025 -0700 time-stamp: optimize resource use * lisp/time-stamp.el (time-stamp-string-preprocess): Replace n-squared string 'concat' with linear list 'push'. diff --git a/lisp/time-stamp.el b/lisp/time-stamp.el index 0f8d540b401..0725908f106 100644 --- a/lisp/time-stamp.el +++ b/lisp/time-stamp.el @@ -535,7 +535,7 @@ and all `time-stamp-format' compatibility." ((fmt-len (length format)) (ind 0) cur-char - (result "") + (result nil) (handle-one-conversion (lambda () (let ((prev-char nil) @@ -779,17 +779,13 @@ and all `time-stamp-format' compatibility." ;; iterate over the format string (while (< ind fmt-len) (setq cur-char (aref format ind)) - (setq - result - (concat - result - (cond - ((eq cur-char ?%) - (funcall handle-one-conversion)) - (t - (char-to-string cur-char))))) + (push (cond ((eq cur-char ?%) + (funcall handle-one-conversion)) + (t + (char-to-string cur-char))) + result) (setq ind (1+ ind))) - result)) + (apply #'concat (nreverse result)))) (defun time-stamp-do-letter-case (change-is-downcase upcase title-case change-case text) commit 1bfbaacc056c23fa7c5c8741b6cdd43201e0a65f Author: Stephen Gildea Date: Wed Mar 12 06:48:55 2025 -0700 time-stamp: refactor for readability * lisp/time-stamp.el (time-stamp-string-preprocess): Move all of the big 'while' loop to the end of the function, to better expose its structure of iterating over the format string. diff --git a/lisp/time-stamp.el b/lisp/time-stamp.el index 4117db71058..0f8d540b401 100644 --- a/lisp/time-stamp.el +++ b/lisp/time-stamp.el @@ -531,18 +531,13 @@ time is used. The time zone is determined by `time-stamp-time-zone'." Optional second argument TIME is only for testing. This is an internal routine implementing extensions to `format-time-string' and all `time-stamp-format' compatibility." - (let ((fmt-len (length format)) - (ind 0) - cur-char - (result "")) - (while (< ind fmt-len) - (setq cur-char (aref format ind)) - (setq - result - (concat - result - (cond - ((eq cur-char ?%) + (let* + ((fmt-len (length format)) + (ind 0) + cur-char + (result "") + (handle-one-conversion + (lambda () (let ((prev-char nil) (field-width "") field-result @@ -780,7 +775,17 @@ and all `time-stamp-format' compatibility." (format (format "%%%s%c" field-width (if (numberp field-result) ?d ?s)) - (or field-result "")))) + (or field-result "")))))) ;end of handle-one-conversion + ;; iterate over the format string + (while (< ind fmt-len) + (setq cur-char (aref format ind)) + (setq + result + (concat + result + (cond + ((eq cur-char ?%) + (funcall handle-one-conversion)) (t (char-to-string cur-char))))) (setq ind (1+ ind))) commit a6abb88fdcc71f2959c95ee5cda57c28719c5a0a Author: Eli Zaretskii Date: Wed Mar 12 14:53:03 2025 +0200 ; * lisp/files.el (executable-find): Doc fix. diff --git a/lisp/files.el b/lisp/files.el index 79dbe5ad53e..2707a4e8bbe 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -1286,9 +1286,9 @@ the value of the variable `exec-path'." (defun executable-find (command &optional remote) "Search for COMMAND in `exec-path' and return the absolute file name. -Return nil if COMMAND is not found anywhere in `exec-path'. If -REMOTE is non-nil, search on the remote host indicated by -`default-directory' instead." +Return nil if COMMAND is not found anywhere in `exec-path'. +If REMOTE is non-nil, search on a remote host if `default-directory' is +remote, otherwise search locally." (if (and remote (file-remote-p default-directory)) (let ((res (locate-file command commit 26f5e6339be08d6a1c8831d87779788d93eeda9b Author: Po Lu Date: Wed Mar 12 17:28:27 2025 +0800 Don't warn about Xft >= 2.3.6 * configure.ac: Don't warn about Xft >= 2.3.6. Clarify warning message printed on old releases. diff --git a/configure.ac b/configure.ac index 253276d8de5..4a7f326ab2b 100644 --- a/configure.ac +++ b/configure.ac @@ -4486,6 +4486,7 @@ fi ### End of font-backend (under any platform) section. ### Start of font-backend (under X11) section. +is_xft_version_outdated=no if test "${HAVE_X11}" = "yes"; then if test $HAVE_CAIRO = yes; then dnl Strict linkers fail with @@ -4534,7 +4535,20 @@ if test "${HAVE_X11}" = "yes"; then if test "${HAVE_XFT}" = "yes"; then AC_DEFINE([HAVE_XFT], [1], [Define to 1 if you have the Xft library.]) - AC_SUBST([XFT_LIBS]) + AC_SUBST([XFT_LIBS]) + AC_CACHE_CHECK([whether libXft is not recent enough to support color fonts], + [emacs_cv_is_xft_version_outdated], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM( + [[ + #include + #include + #if XftVersion < 20306 + #error "Xft < 2.3.6" + #endif /* XftVersion < 20306 */ + ]], [])], + [emacs_cv_is_xft_version_outdated=no], + [emacs_cv_is_xft_version_outdated=yes])]) + is_xft_version_outdated=$emacs_cv_is_xft_version_outdated C_SWITCH_X_SITE="$C_SWITCH_X_SITE $XFT_CFLAGS" fi # "${HAVE_XFT}" = "yes" CPPFLAGS=$OLD_CPPFLAGS @@ -7863,11 +7877,11 @@ you can continue to support by using '$0 --with-pop'.]) esac fi -if test "${HAVE_XFT}" = yes; then - AC_MSG_WARN([This configuration uses libXft, which has a number of - font rendering issues in its earlier releases. Please consider - using Cairo graphics instead (they are auto-detected if the - relevant development headers are installed).]) +if test "${HAVE_XFT}" = yes && test "$is_xft_version_outdated" = "yes"; then + AC_MSG_WARN([This configuration uses a version of libXft earlier than 2.3.6, + which is impacted by a number of rendering issues up to and including + crashes. Please consider using Cairo graphics instead (they are + auto-detected if the relevant development headers are installed).]) fi if test "${HAVE_CAIRO}" = "yes" && test "${HAVE_HARFBUZZ}" = no; then