diff --git a/admin/notes/repo b/admin/notes/repo index b4535bcb556..c5caec11e35 100644 --- a/admin/notes/repo +++ b/admin/notes/repo @@ -77,16 +77,6 @@ variable in admin/merge-gnulib before running it. If you remove a gnulib module, or if a gnulib module removes a file, then remove the corresponding files by hand. -* How to merge changes from emacs-24 to master - -[The section on git merge procedure has not yet been written.] - -You may see conflicts in autoload md5sums in comments. Strictly -speaking, the right thing to do is merge everything else, resolve the -conflict by choosing either the master or branch version, then run -'make -C lisp autoloads' to update the md5sums to the correct master -value before committing. - * Re-adding a file that has been removed from the repository Let's suppose you've done: diff --git a/doc/lispref/control.texi b/doc/lispref/control.texi index 80ed2ce899b..27ce932433d 100644 --- a/doc/lispref/control.texi +++ b/doc/lispref/control.texi @@ -322,25 +322,46 @@ There's a number of variations on this theme, and they're briefly described below. @defmac if-let* varlist then-form else-forms... -Evaluate each binding in @var{varlist} in turn, like in @code{let*} -(@pxref{Local Variables}), stopping if a binding value is @code{nil}. -If all are non-@code{nil}, return the value of @var{then-form}, -otherwise the last form in @var{else-forms}. +Evaluate each binding in @var{varlist}, stopping if a binding value is +@code{nil}. If all are non-@code{nil}, return the value of +@var{then-form}, otherwise the last form in @var{else-forms}. + +Each element of @code{varlist} has the form @w{@code{(@var{symbol} +@var{value-form})}}: @var{value-form} is evaluated and @var{symbol} is +locally bound to the result. Bindings are sequential, as in @code{let*} +(@pxref{Local Variables}). As a special case, @var{symbol} can be +omitted if only the test result of @var{value-form} is of interest: +@var{value-form} is evaluated and checked for @code{nil}, but its value +is not bound. @end defmac @defmac when-let* varlist then-forms... -Like @code{if-let*}, but without @var{else-forms}. +Evaluate each binding in @var{varlist}, stopping if a binding value is +@code{nil}. If all are non-@code{nil}, return the value of the last +form in @var{then-forms}. + +@var{varlist} has the same form as in @code{if-let*}: Each element of +@code{varlist} has the form @w{@code{(@var{symbol} @var{value-form})}}, +in which @var{value-form} is evaluated and @var{symbol} is locally bound +to the result. Bindings are sequential, as in @code{let*} (@pxref{Local +Variables}). As a special case, @var{symbol} can be omitted if only the +test result of @var{value-form} is of interest: @var{value-form} is +evaluated and checked for @code{nil}, but its value is not bound. @end defmac @defmac and-let* varlist then-forms... -Like @code{when-let*}, but in addition, if there are no -@var{then-forms} and all the bindings evaluate to non-@code{nil}, return +Evaluate each binding in @var{varlist}, stopping if a binding value is +@code{nil}. If all are non-@code{nil}, return the value of the last +form in @var{then-forms}, or, if there are no @var{then-forms}, return the value of the last binding. -@end defmac -@defmac while-let spec then-forms... -Like @code{when-let*}, but repeat until a binding in @var{spec} is -@code{nil}. The return value is always @code{nil}. +@var{varlist} has the same form as in @code{if-let*}: Each element of +@code{varlist} has the form @w{@code{(@var{symbol} @var{value-form})}}, +in which @var{value-form} is evaluated and @var{symbol} is locally bound +to the result. Bindings are sequential, as in @code{let*} (@pxref{Local +Variables}). As a special case, @var{symbol} can be omitted if only the +test result of @var{value-form} is of interest: @var{value-form} is +evaluated and checked for @code{nil}, but its value is not bound. @end defmac Some Lisp programmers follow the convention that @code{and} and @@ -348,6 +369,27 @@ Some Lisp programmers follow the convention that @code{and} and @code{when} and @code{when-let*} are for forms evaluated for side-effect with returned values ignored. +A similar macro exists to run a loop until one binding evaluates to +@code{nil}: + +@defmac while-let spec then-forms... +Evaluate each binding in @var{spec} in turn, stopping if a binding value +is @code{nil}. If all are non-@code{nil}, execute @var{then-forms}, +then repeat the loop. Note that when the loop is repeated, the +@var{value-forms} in @var{spec} are re-evaluated and the bindings are +established anew. + +@var{varlist} has the same form as in @code{if-let*}: Each element of +@code{varlist} has the form @w{@code{(@var{symbol} @var{value-form})}}, +in which @var{value-form} is evaluated and @var{symbol} is locally bound +to the result. Bindings are sequential, as in @code{let*} (@pxref{Local +Variables}). As a special case, @var{symbol} can be omitted if only the +test result of @var{value-form} is of interest: @var{value-form} is +evaluated and checked for @code{nil}, but its value is not bound. + +The return value of @code{while-let} is always @code{nil}. +@end defmac + @node Combining Conditions @section Constructs for Combining Conditions @cindex combining conditions diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 7ada57d3d9c..a7c5ae561be 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -2805,7 +2805,11 @@ being pressed. If it is @code{pressed-button}, the box looks like a If you use the @code{:box} face attribute on strings displayed instead of buffer text via the @code{display} text property, special considerations might apply if the surrounding buffer text also has the -@code{:box} face attribute. @xref{Replacing Specs}. +@code{:box} face attribute. @xref{Replacing Specs}. Also note that the +vertical lines of the box are only drawn when @code{:box} attribute +changes from @code{nil} to non-@code{nil} or vice versa; two consecutive +face properties with a non-@code{nil} @code{:box} attribute will be +displayed without the vertical line between them. @item :inverse-video Whether or not characters should be displayed in inverse video. The diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi index af11e498d86..0e9124920d1 100644 --- a/doc/lispref/variables.texi +++ b/doc/lispref/variables.texi @@ -1096,7 +1096,7 @@ x ; @r{Note that @code{x} has no global value.} @end example @noindent -The @code{let} binding defines a lexical environment in which the +Here, the @code{let} binding defines a lexical environment in which the variable @code{x} is locally bound to 0. Within this binding construct, we define a lambda expression which increments @code{x} by one and returns the incremented value. This lambda expression is @@ -1113,6 +1113,12 @@ functions which take a symbol argument (like @code{symbol-value}, variable's dynamic binding (i.e., the contents of its symbol's value cell). + Note also that variables may be declared special, in which case they +will use dynamic binding, even for new bindings such as a @code{let} +binding. Depending on how the variable is declared, it can be +special globally, for a single file, or for a portion of a file. +@xref{Dynamic Binding} for details. + @node Dynamic Binding @subsection Dynamic Binding diff --git a/lisp/calendar/diary-lib.el b/lisp/calendar/diary-lib.el index 63bbae4d8ed..5d582f973bc 100644 --- a/lisp/calendar/diary-lib.el +++ b/lisp/calendar/diary-lib.el @@ -235,7 +235,8 @@ use `diary-list-entries-hook', which runs only for the main diary file." :type 'hook :options '(diary-bahai-list-entries diary-hebrew-list-entries - diary-islamic-list-entries) + diary-islamic-list-entries + diary-chinese-list-entries) :group 'diary) (defcustom diary-nongregorian-marking-hook nil @@ -252,7 +253,8 @@ use `diary-mark-entries-hook', which runs only for the main diary file." :type 'hook :options '(diary-bahai-mark-entries diary-hebrew-mark-entries - diary-islamic-mark-entries) + diary-islamic-mark-entries + diary-chinese-mark-entries) :group 'diary) (defcustom diary-print-entries-hook #'lpr-buffer diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 9bbb78e0862..cbb103cfaf7 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -35,7 +35,7 @@ ;; To use these modes by default, assuming you have the respective ;; tree-sitter grammars available, do one of the following: ;; -;; - Add one or mode of the following to your init file: +;; - Add one or more of the following lines to your init file: ;; ;; (add-to-list 'major-mode-remap-alist '(c-mode . c-ts-mode)) ;; (add-to-list 'major-mode-remap-alist '(c++-mode . c++-ts-mode)) @@ -150,10 +150,11 @@ symbol." (defcustom c-ts-mode-indent-style 'gnu "Style used for indentation. -The selected style could be one of GNU, K&R, LINUX or BSD. If -one of the supplied styles doesn't suffice, the value could be -a function instead. This function is expected to return a list -that follows the form of `treesit-simple-indent-rules'." +The selected style could be one of GNU, K&R, LINUX or BSD. If the +supplied styles don't suffice, the value could be a function instead. +This function takes no arguments and is expected to return a list of +indent RULEs as described in `treesit-simple-indent-rules'. Note that +the list of RULEs doesn't need to contain the language symbol." :version "29.1" :type '(choice (symbol :tag "Gnu" gnu) (symbol :tag "K&R" k&r) @@ -1277,9 +1278,6 @@ BEG and END are described in `treesit-range-rules'." `((c ,@c-ts-mode--thing-settings) (cpp ,@c-ts-mode--thing-settings))) - ;; Nodes like struct/enum/union_specifier can appear in - ;; function_definitions, so we need to find the top-level node. - (setq-local treesit-defun-prefer-top-level t) ;; When the code is in incomplete state, try to make a better guess ;; about which node to indent against. @@ -1360,46 +1358,49 @@ in your init files." (treesit-parser-create 'c nil nil 'for-each))) (let ((primary-parser (treesit-parser-create 'c))) - ;; Comments. - (setq-local comment-start "/* ") - (setq-local comment-end " */") - ;; Indent. - (setq-local treesit-simple-indent-rules - (c-ts-mode--get-indent-style 'c)) - ;; Font-lock. + ;; Comments. + (setq-local comment-start "/* ") + (setq-local comment-end " */") + ;; Indent. + (setq-local treesit-simple-indent-rules + (c-ts-mode--get-indent-style 'c)) + ;; Font-lock. + (setq-local treesit-font-lock-settings + (c-ts-mode--font-lock-settings 'c)) + ;; Navigation. + ;; + ;; Nodes like struct/enum/union_specifier can appear in + ;; function_definitions, so we need to find the top-level node. + (setq-local treesit-defun-tactic 'top-level) + (treesit-major-mode-setup) + + ;; Emacs source support: handle DEFUN and FOR_EACH_* gracefully. + (when c-ts-mode-emacs-sources-support + (setq-local add-log-current-defun-function + #'c-ts-mode--emacs-current-defun-name) + + (setq-local treesit-range-settings + (treesit-range-rules 'c-ts-mode--emacs-set-ranges)) + + (setq-local treesit-language-at-point-function + (lambda (_pos) 'c)) + (treesit-font-lock-recompute-features '(emacs-devel))) + + ;; Inject doxygen parser for comment. + (when (and c-ts-mode-enable-doxygen (treesit-ready-p 'doxygen t)) + (setq-local treesit-primary-parser primary-parser) (setq-local treesit-font-lock-settings - (c-ts-mode--font-lock-settings 'c)) - ;; Navigation. - (setq-local treesit-defun-tactic 'top-level) - (treesit-major-mode-setup) - - ;; Emacs source support: handle DEFUN and FOR_EACH_* gracefully. - (when c-ts-mode-emacs-sources-support - (setq-local add-log-current-defun-function - #'c-ts-mode--emacs-current-defun-name) - - (setq-local treesit-range-settings - (treesit-range-rules 'c-ts-mode--emacs-set-ranges)) - - (setq-local treesit-language-at-point-function - (lambda (_pos) 'c)) - (treesit-font-lock-recompute-features '(emacs-devel))) - - ;; Inject doxygen parser for comment. - (when (and c-ts-mode-enable-doxygen (treesit-ready-p 'doxygen t)) - (setq-local treesit-primary-parser primary-parser) - (setq-local treesit-font-lock-settings - (append - treesit-font-lock-settings - c-ts-mode-doxygen-comment-font-lock-settings)) - (setq-local treesit-range-settings - (treesit-range-rules - :embed 'doxygen - :host 'c - :local t - `(((comment) @cap - (:match - ,c-ts-mode--doxygen-comment-regex @cap))))))))) + (append + treesit-font-lock-settings + c-ts-mode-doxygen-comment-font-lock-settings)) + (setq-local treesit-range-settings + (treesit-range-rules + :embed 'doxygen + :host 'c + :local t + `(((comment) @cap + (:match + ,c-ts-mode--doxygen-comment-regex @cap))))))))) (derived-mode-add-parents 'c-ts-mode '(c-mode)) diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index f74b8ab1c46..57889338650 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -3918,7 +3918,6 @@ See `treesit-thing-settings' for more information.") ;; Indent. (setq-local treesit-simple-indent-rules js--treesit-indent-rules) ;; Navigation. - (setq-local treesit-defun-prefer-top-level t) (setq-local treesit-defun-type-regexp (rx (or "class_declaration" "method_definition" diff --git a/lisp/progmodes/php-ts-mode.el b/lisp/progmodes/php-ts-mode.el index b0271c4ea6a..b6fe17f7d41 100644 --- a/lisp/progmodes/php-ts-mode.el +++ b/lisp/progmodes/php-ts-mode.el @@ -84,7 +84,7 @@ ;;; Install treesitter language parsers (defvar php-ts-mode--language-source-alist - '((php . ("https://github.com/tree-sitter/tree-sitter-php" "v0.23.5" "php/src")) + '((php . ("https://github.com/tree-sitter/tree-sitter-php" "v0.23.11" "php/src")) (phpdoc . ("https://github.com/claytonrcarter/tree-sitter-phpdoc")) (html . ("https://github.com/tree-sitter/tree-sitter-html" "v0.23.0")) (javascript . ("https://github.com/tree-sitter/tree-sitter-javascript" "v0.23.0")) @@ -477,16 +477,20 @@ PARENT is its parent." (treesit-node-start parent) (line-end-position)))))) -(defun php-ts-mode--js-css-tag-bol (node _parent &rest _) +(defun php-ts-mode--js-css-tag-bol (_node parent &rest _) "Find the first non-space characters of html tags