commit ed97d15a084470a98186bf8765ab0d5f89911641 (HEAD, refs/remotes/origin/master) Author: Mattias EngdegÄrd Date: Tue Jun 15 19:48:45 2021 +0200 Remove outdated advise from manual * doc/lispref/modes.texi (Search-based Fontification): Remove paragraph that has been unnecessary and confusing ever since regexp-opt stopped using capturing brackets more than 21 years ago. diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 02064e7a37..5869f53636 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -2985,10 +2985,6 @@ highlighted (instead of the entire text that @var{matcher} matched). ("fu\\(bar\\)" . 1) @end example -If you use @code{regexp-opt} to produce the regular expression -@var{matcher}, you can use @code{regexp-opt-depth} (@pxref{Regexp -Functions}) to calculate the value for @var{subexp}. - @item (@var{matcher} . @var{facespec}) In this kind of element, @var{facespec} is an expression whose value specifies the face to use for highlighting. In the simplest case, commit eac34b52f6764808b0a8a1c3a5e9a1f703e55c7a Author: Mattias EngdegÄrd Date: Tue Jun 15 19:57:38 2021 +0200 ; * lisp/progmodes/hideif.el (hif-unicode-prefix-regexp): Stray `\`. diff --git a/lisp/progmodes/hideif.el b/lisp/progmodes/hideif.el index d127575255..4a1da62c7e 100644 --- a/lisp/progmodes/hideif.el +++ b/lisp/progmodes/hideif.el @@ -694,7 +694,7 @@ that form should be displayed.") "\\|\\(\\w+\\)")) ;; C++11 Unicode string literals (L"" u8"" u"" U"" R"" LR"" u8R"" uR"") -(defconst hif-unicode-prefix-regexp "\\(?:u8R?\\|[uUL]R?\\\|R\\)") +(defconst hif-unicode-prefix-regexp "\\(?:u8R?\\|[uUL]R?\\|R\\)") (defconst hif-string-literal-regexp (concat hif-unicode-prefix-regexp "?" "\\(\"\\(?:[^\"\\]\\|\\\\.\\)*\"\\)")) commit d9698faa345a99b4a55bb02ecb324b0d8dcd2997 Author: Pip Cet Date: Tue Mar 2 20:38:23 2021 +0000 Prepare pdumper dump file in memory, write it in one go (Bug#46881) * src/pdumper.c (struct dump_context): Add buf, buf_size, max_offset fields. (dump_grow_buffer): New function. (dump_write): Use memcpy, not an actual emacs_write. (dump_seek): Keep track of maximum seen offset. Don't actually seek. (Fdump_emacs_portable): Write out the file contents when done. diff --git a/src/pdumper.c b/src/pdumper.c index dfc7388b63..7730ea3d06 100644 --- a/src/pdumper.c +++ b/src/pdumper.c @@ -489,6 +489,10 @@ struct dump_context { /* Header we'll write to the dump file when done. */ struct dump_header header; + /* Data that will be written to the dump file. */ + void *buf; + dump_off buf_size; + dump_off max_offset; Lisp_Object old_purify_flag; Lisp_Object old_post_gc_hook; @@ -597,6 +601,13 @@ static struct link_weight const /* Dump file creation */ +static void dump_grow_buffer (struct dump_context *ctx) +{ + ctx->buf = xrealloc (ctx->buf, ctx->buf_size = (ctx->buf_size ? + (ctx->buf_size * 2) + : 8 * 1024 * 1024)); +} + static dump_off dump_object (struct dump_context *ctx, Lisp_Object object); static dump_off dump_object_for_offset (struct dump_context *ctx, Lisp_Object object); @@ -763,8 +774,9 @@ dump_write (struct dump_context *ctx, const void *buf, dump_off nbyte) eassert (nbyte == 0 || buf != NULL); eassert (ctx->obj_offset == 0); eassert (ctx->flags.dump_object_contents); - if (emacs_write (ctx->fd, buf, nbyte) < nbyte) - report_file_error ("Could not write to dump file", ctx->dump_filename); + while (ctx->offset + nbyte > ctx->buf_size) + dump_grow_buffer (ctx); + memcpy ((char *)ctx->buf + ctx->offset, buf, nbyte); ctx->offset += nbyte; } @@ -844,10 +856,9 @@ dump_tailq_pop (struct dump_tailq *tailq) static void dump_seek (struct dump_context *ctx, dump_off offset) { + if (ctx->max_offset < ctx->offset) + ctx->max_offset = ctx->offset; eassert (ctx->obj_offset == 0); - if (lseek (ctx->fd, offset, SEEK_SET) < 0) - report_file_error ("Setting file position", - ctx->dump_filename); ctx->offset = offset; } @@ -4270,6 +4281,12 @@ types. */) ctx->header.magic[0] = dump_magic[0]; dump_seek (ctx, 0); dump_write (ctx, &ctx->header, sizeof (ctx->header)); + if (emacs_write (ctx->fd, ctx->buf, ctx->max_offset) < ctx->max_offset) + report_file_error ("Could not write to dump file", ctx->dump_filename); + xfree (ctx->buf); + ctx->buf = NULL; + ctx->buf_size = 0; + ctx->max_offset = 0; dump_off header_bytes = header_end - header_start, commit db106ea88b41e7b293f18a587cbe43685cb769a6 Author: pillule Date: Wed Jun 16 02:31:58 2021 +0300 User option to choose a function triggered by windmove-create (bug#48917) * lisp/windmove.el (windmove-create-window): Add a defcustom choice. (windmove-do-window-select): Trigger custom functions, update the docstring. diff --git a/lisp/windmove.el b/lisp/windmove.el index ac146ab2dc..3c1f20aa26 100644 --- a/lisp/windmove.el +++ b/lisp/windmove.el @@ -144,9 +144,18 @@ is inactive." "Whether movement off the edge of the frame creates a new window. If this variable is set to t, moving left from the leftmost window in a frame will create a new window on the left, and similarly for the other -directions." - :type 'boolean - :version "27.1") +directions. +This variable may also be a function to be called in this circumstance +by `windmove-do-window-select'. The function should accept then as +argument the DIRECTION targeted, an interactive ARG and a WINDOW +corresponding to the currently selected window. It should also return +a valid window that `windmove-do-window-select' will select, +or the symbol `no-select' to ignore that final selection." + :type '(choice + (const :tag "Don't create new windows" nil) + (const :tag "Create new windows" t) + (function :tag "Provide a function")) + :version "28.1") ;; If your Emacs sometimes places an empty column between two adjacent ;; windows, you may wish to set this delta to 2. @@ -356,19 +365,23 @@ use the left or top edge of WINDOW as reference point." "Move to the window at direction DIR as seen from WINDOW. DIR, ARG, and WINDOW are handled as by `windmove-find-other-window'. If no window is at direction DIR, an error is signaled. -If `windmove-create-window' is non-nil, try to create a new window +If `windmove-create-window' is a function, call that function with +DIR, ARG and WINDOW. If it is non-nil, try to create a new window in direction DIR instead." (let ((other-window (windmove-find-other-window dir arg window))) (when (and windmove-create-window (or (null other-window) (and (window-minibuffer-p other-window) (not (minibuffer-window-active-p other-window))))) - (setq other-window (split-window window nil dir))) + (setq other-window (if (functionp windmove-create-window) + (funcall windmove-create-window dir arg window) + (split-window window nil dir)))) (cond ((null other-window) (user-error "No window %s from selected window" dir)) ((and (window-minibuffer-p other-window) (not (minibuffer-window-active-p other-window))) (user-error "Minibuffer is inactive")) + ((eq other-window 'no-select)) (t (select-window other-window))))) commit 0367d17482804cd4a47d6fcf0201cdded7fc88dc Author: pillule Date: Wed Jun 16 02:23:13 2021 +0300 User option to select 'no-other-window' with windmove (bug#48916) * lisp/windmove.el (windmove-wrap-around): Remove superfluous :group tag. (windmove-create-window): Remove superfluous :group tag. (windmove-window-distance-delta): Remove superfluous :group tag. (windmove-allow-all-windows): Add new user option to allow the commands of windmove to target windows with the 'no-other-window parameter. (windmove-find-other-window): Use windmove-allow-all-windows. (windmove-display-no-select): Remove superfluous :group tag. (windmove-display-in-direction): Use windmove-allow-all-windows. (windmove-delete-in-direction): Use windmove-allow-all-windows. (windmove-swap-states-in-direction): Use windmove-allow-all-windows. (windmove-default-keybindings): Remove superfluous :group tag. (windmove-display-default-keybindings): Remove superfluous :group tag. (windmove-delete-default-keybindings): Remove superfluous :group tag. (windmove-swap-states-default-keybindings): Remove superfluous :group tag. diff --git a/lisp/windmove.el b/lisp/windmove.el index f558903681..ac146ab2dc 100644 --- a/lisp/windmove.el +++ b/lisp/windmove.el @@ -138,8 +138,7 @@ If this variable is set to t, moving left from the leftmost window in a frame will find the rightmost one, and similarly for the other directions. The minibuffer is skipped over in up/down movements if it is inactive." - :type 'boolean - :group 'windmove) + :type 'boolean) (defcustom windmove-create-window nil "Whether movement off the edge of the frame creates a new window. @@ -147,7 +146,6 @@ If this variable is set to t, moving left from the leftmost window in a frame will create a new window on the left, and similarly for the other directions." :type 'boolean - :group 'windmove :version "27.1") ;; If your Emacs sometimes places an empty column between two adjacent @@ -157,11 +155,18 @@ directions." Measured in characters either horizontally or vertically; setting this to a value larger than 1 may be useful in getting around window- placement bugs in old versions of Emacs." - :type 'number - :group 'windmove) + :type 'number) (make-obsolete-variable 'windmove-window-distance-delta "no longer used." "27.1") +(defcustom windmove-allow-all-windows nil + "Whether the windmove commands are allowed to target all type of windows. +If this variable is set to non-nil, all windmove commmands will +ignore the `no-other-window' parameter applied by `display-buffer-alist' +or `set-window-parameter'." + :type 'boolean + :version "28.1") + ;; Note: ;; @@ -342,7 +347,8 @@ WINDOW must be a live window and defaults to the selected one. Optional ARG, if negative, means to use the right or bottom edge of WINDOW as reference position, instead of `window-point'; if positive, use the left or top edge of WINDOW as reference point." - (window-in-direction dir window nil arg windmove-wrap-around t)) + (window-in-direction dir window windmove-allow-all-windows + arg windmove-wrap-around t)) ;; Selects the window that's hopefully at the location returned by ;; `windmove-find-other-window', or screams if there's no window there. @@ -480,7 +486,6 @@ Default value of MODIFIERS is `shift'." (defcustom windmove-display-no-select nil "Whether the window should be selected after displaying the buffer in it." :type 'boolean - :group 'windmove :version "27.1") (defun windmove-display-in-direction (dir &optional arg) @@ -517,7 +522,7 @@ When `switch-to-buffer-obey-display-actions' is non-nil, ((eq dir 'same-window) (selected-window)) (t (window-in-direction - dir nil nil + dir nil windmove-allow-all-windows (and arg (prefix-numeric-value arg)) windmove-wrap-around 'nomini))))) (unless window @@ -606,8 +611,8 @@ With `M-0' prefix, delete the selected window and select the window at direction DIR. When `windmove-wrap-around' is non-nil, takes the window from the opposite side of the frame." - (let ((other-window (window-in-direction dir nil nil arg - windmove-wrap-around 'nomini))) + (let ((other-window (window-in-direction dir nil windmove-allow-all-windows + arg windmove-wrap-around 'nomini))) (cond ((null other-window) (user-error "No window %s from selected window" dir)) (t @@ -680,8 +685,8 @@ Default value of PREFIX is `C-x' and MODIFIERS is `shift'." "Swap the states of the selected window and the window at direction DIR. When `windmove-wrap-around' is non-nil, takes the window from the opposite side of the frame." - (let ((other-window (window-in-direction dir nil nil nil - windmove-wrap-around 'nomini))) + (let ((other-window (window-in-direction dir nil windmove-allow-all-windows + nil windmove-wrap-around 'nomini))) (cond ((or (null other-window) (window-minibuffer-p other-window)) (user-error "No window %s from selected window" dir)) (t @@ -761,8 +766,7 @@ See `windmove-default-keybindings' for more detail." (null val)) (set-default sym val)) :type windmove--default-keybindings-type - :version "28.1" - :group 'windmove) + :version "28.1") (defcustom windmove-display-default-keybindings nil "Default keybindings for windmove directional buffer display commands. @@ -780,8 +784,7 @@ See `windmove-display-default-keybindings' for more detail." (null val)) (set-default sym val)) :type windmove--default-keybindings-type - :version "28.1" - :group 'windmove) + :version "28.1") (defcustom windmove-delete-default-keybindings nil "Default keybindings for windmove directional window deletion commands. @@ -796,8 +799,7 @@ See `windmove-delete-default-keybindings' for more detail." (null val)) (set-default sym val)) :type windmove--default-keybindings-type - :version "28.1" - :group 'windmove) + :version "28.1") (defcustom windmove-swap-states-default-keybindings nil "Default keybindings for windmove's directional window swap-state commands. @@ -812,8 +814,7 @@ See `windmove-swap-states-default-keybindings' for more detail." (null val)) (set-default sym val)) :type windmove--default-keybindings-type - :version "28.1" - :group 'windmove) + :version "28.1") (provide 'windmove) commit a8721a333d5cf9080406bd4d9f723bda7a4a8402 Author: Lars Ingebrigtsen Date: Tue Jun 15 20:58:01 2021 +0200 Make help-view-source more robust * lisp/help-mode.el (help-view-source): Check the right thing to see if we can jump to the source file. diff --git a/lisp/help-mode.el b/lisp/help-mode.el index 7450d73332..48cf435f97 100644 --- a/lisp/help-mode.el +++ b/lisp/help-mode.el @@ -733,7 +733,7 @@ See `help-make-xrefs'." (defun help-view-source () "View the source of the current help item." (interactive nil help-mode) - (unless help-mode--current-data + (unless (plist-get help-mode--current-data :file) (error "Source file for the current help item is not defined")) (help-function-def--button-function (plist-get help-mode--current-data :symbol) (plist-get help-mode--current-data :file))) commit 6fc48df5ae6244485a963d138c6441c50396deed Author: Lars Ingebrigtsen Date: Tue Jun 15 20:51:00 2021 +0200 Add new convenience commands for *Help* * doc/emacs/help.texi (Help Mode): Document it (bug#36767). * lisp/help-fns.el (help-fns-function-description-header) (describe-variable, describe-face, describe-keymap) (describe-mode): Add the required data. * lisp/help-mode.el (help-mode-map): Add 'i' and 's'. (help-mode--current-data): New variable. (help-mode): Make it local. (help-view-source, help-goto-info): New commands. diff --git a/doc/emacs/help.texi b/doc/emacs/help.texi index 90a2ddc809..8c24a926af 100644 --- a/doc/emacs/help.texi +++ b/doc/emacs/help.texi @@ -451,6 +451,11 @@ Go forward to the next help topic (@code{help-go-forward}). @item C-c C-b @itemx l Go back to the previous help topic (@code{help-go-back}). +@item s +View the source of the current help topic (if any) +(@code{help-view-source}). +@item i +Look up the current topic in the manual(s) (@code{help-goto-info}). @end table @cindex hyperlink diff --git a/etc/NEWS b/etc/NEWS index 85ef6e4ba3..da1372baf4 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1124,6 +1124,15 @@ This change is for better compatibility with old versions of non-GNU ** Help ++++ +*** New command 'help-view-source' ('s') +This command will view the source file (if any) of the current help +topic. + ++++ +*** New command 'help-goto-info' ('i') +This command will look up the current symbol (if any) in Info. + --- *** The 'help-for-help' ('C-h C-h') screen has been redesigned. diff --git a/lisp/help-fns.el b/lisp/help-fns.el index 133763add1..f9804c705b 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -887,7 +887,9 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)." nil t) (help-xref-button 1 'help-function real-def))))) - (when file-name + (if (not file-name) + (with-current-buffer standard-output + (setq help-mode--current-data (list :symbol function))) ;; We used to add .el to the file name, ;; but that's completely wrong when the user used load-file. (princ (format-message " in `%s'" @@ -896,6 +898,8 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)." (help-fns-short-filename file-name)))) ;; Make a hyperlink to the library. (with-current-buffer standard-output + (setq help-mode--current-data (list :symbol function + :file file-name)) (save-excursion (re-search-backward (substitute-command-keys "`\\([^`']+\\)'") nil t) @@ -1070,7 +1074,10 @@ it is displayed along with the global value." "C source code" (help-fns-short-filename file-name)))) (with-current-buffer standard-output - (save-excursion + (setq help-mode--current-data + (list :symbol variable + :file file-name)) + (save-excursion (re-search-backward (substitute-command-keys "`\\([^`']+\\)'") nil t) @@ -1079,6 +1086,8 @@ it is displayed along with the global value." (if valvoid "It is void as a variable." "Its ")) + (with-current-buffer standard-output + (setq help-mode--current-data (list :symbol variable))) (if valvoid " is void as a variable." (substitute-command-keys "'s "))))) @@ -1448,7 +1457,10 @@ If FRAME is omitted or nil, use the selected frame." (concat "\\(" customize-label "\\)") nil t) (help-xref-button 1 'help-customize-face f))) (setq file-name (find-lisp-object-file-name f 'defface)) - (when file-name + (if (not file-name) + (setq help-mode--current-data (list :symbol f)) + (setq help-mode--current-data (list :symbol f + :file file-name)) (princ (substitute-command-keys "Defined in `")) (princ (help-fns-short-filename file-name)) (princ (substitute-command-keys "'")) @@ -1738,7 +1750,9 @@ keymap value." (unless used-gentemp (princ (format-message "%S is a keymap variable" keymap)) (if (not file-name) - (princ ".\n\n") + (progn + (setq help-mode--current-data (list :symbol keymap)) + (princ ".\n\n")) (princ (format-message " defined in `%s'.\n\n" (if (eq file-name 'C-source) @@ -1748,6 +1762,8 @@ keymap value." (re-search-backward (substitute-command-keys "`\\([^`']+\\)'") nil t) + (setq help-mode--current-data (list :symbol keymap + :file file-name)) (help-xref-button 1 'help-variable-def keymap file-name)))) (when (and (not (equal "" doc)) doc) @@ -1855,7 +1871,8 @@ documentation for the major and minor modes of that buffer." (princ " mode") (let* ((mode major-mode) (file-name (find-lisp-object-file-name mode nil))) - (when file-name + (if (not file-name) + (setq help-mode--current-data (list :symbol mode)) (princ (format-message " defined in `%s'" (help-fns-short-filename file-name))) ;; Make a hyperlink to the library. @@ -1863,6 +1880,8 @@ documentation for the major and minor modes of that buffer." (save-excursion (re-search-backward (substitute-command-keys "`\\([^`']+\\)'") nil t) + (setq help-mode--current-data (list :symbol mode + :file file-name)) (help-xref-button 1 'help-function-def mode file-name))))) (let ((fundoc (help-split-fundoc (documentation major-mode) nil 'doc))) (with-current-buffer standard-output diff --git a/lisp/help-mode.el b/lisp/help-mode.el index c7eaae5feb..7450d73332 100644 --- a/lisp/help-mode.el +++ b/lisp/help-mode.el @@ -44,6 +44,8 @@ (define-key map [XF86Forward] 'help-go-forward) (define-key map "\C-c\C-c" 'help-follow-symbol) (define-key map "\r" 'help-follow) + (define-key map "s" 'help-view-source) + (define-key map "i" 'help-goto-info) map) "Keymap for Help mode.") @@ -61,7 +63,11 @@ ["Move to Previous Button" backward-button :help "Move to the Previous Button in the help buffer"] ["Move to Next Button" forward-button - :help "Move to the Next Button in the help buffer"])) + :help "Move to the Next Button in the help buffer"] + ["View Source" help-view-source + :help "Go to the source file for the current help item"] + ["Goto Info" help-goto-info + :help "Go to the info node for the current help item"])) (defvar help-mode-tool-bar-map (let ((map (make-sparse-keymap))) @@ -323,6 +329,7 @@ The format is (FUNCTION ARGS...).") 'help-echo (purecopy "mouse-2, RET: show corresponding NEWS announcement")) (defvar bookmark-make-record-function) +(defvar help-mode--current-data nil) ;;;###autoload (define-derived-mode help-mode special-mode "Help" @@ -334,6 +341,7 @@ Commands: #'help-mode-revert-buffer) (setq-local tool-bar-map help-mode-tool-bar-map) + (setq-local help-mode--current-data nil) (setq-local bookmark-make-record-function #'help-bookmark-make-record)) @@ -722,6 +730,22 @@ See `help-make-xrefs'." (help-xref-go-forward (current-buffer)) (user-error "No next help buffer"))) +(defun help-view-source () + "View the source of the current help item." + (interactive nil help-mode) + (unless help-mode--current-data + (error "Source file for the current help item is not defined")) + (help-function-def--button-function (plist-get help-mode--current-data :symbol) + (plist-get help-mode--current-data :file))) + +(defun help-goto-info () + "View the *info* node of the current help item." + (interactive nil help-mode) + (unless help-mode--current-data + (error "No symbol to look up in the current buffer")) + (info-lookup-symbol (plist-get help-mode--current-data :symbol) + 'emacs-lisp-mode)) + (defun help-do-xref (_pos function args) "Call the help cross-reference function FUNCTION with args ARGS. Things are set up properly so that the resulting help-buffer has commit 6ae5a59e5275a54a91092ed5c50fe2b42748784a Author: Lars Ingebrigtsen Date: Tue Jun 15 18:36:29 2021 +0200 Clarify (interactive "K") in the manual * doc/lispref/commands.texi (Interactive Codes): Clarify (interactive "K") (bug#37146). diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 8199ece110..f30419c3ee 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -454,10 +454,13 @@ This kind of input is used by commands such as @code{describe-key} and @code{global-set-key}. @item K -A key sequence, whose definition you intend to change. This works like -@samp{k}, except that it suppresses, for the last input event in the key -sequence, the conversions that are normally used (when necessary) to -convert an undefined key into a defined one. +A key sequence on a form that can be used as input to functions like +@code{define-key}. This works like @samp{k}, except that it +suppresses, for the last input event in the key sequence, the +conversions that are normally used (when necessary) to convert an +undefined key into a defined one (@pxref{Key Sequence Input}), so this +form is usually used when prompting for a new key sequence that is to +be bound to a command. @item m @cindex marker argument commit 9dde254e96417167fcd90f2af9ca8d2f656024e8 Author: Eli Zaretskii Date: Tue Jun 15 18:10:45 2021 +0300 ; * etc/NEWS: Fix a typo in the recent change. diff --git a/etc/NEWS b/etc/NEWS index 30114cab2f..85ef6e4ba3 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2852,8 +2852,9 @@ customize them. +++ ** New function 'syntax-class-to-char'. -This does the almost the opposite of 'string-to-syntax' -- it returns -the syntax descriptor (a character) given a raw syntax descriptor. +This does almost the opposite of 'string-to-syntax' -- it returns the +syntax descriptor (a character) given a raw syntax descriptor (an +integer). +++ ** New function 'buffer-local-boundp'. commit 8be9d4a1568c34aed753b085d5d33daef5dfa797 Author: Julian Scheid Date: Tue Jun 15 17:01:49 2021 +0200 Allow ERT tests to output the failure reasons, too * lisp/emacs-lisp/ert.el (ert-reason-for-test-result): New function. (ert-run-tests-batch): Output failure or skip reason (bug#47071). diff --git a/doc/misc/ert.texi b/doc/misc/ert.texi index a4e2cb506a..fafdb8c4eb 100644 --- a/doc/misc/ert.texi +++ b/doc/misc/ert.texi @@ -347,6 +347,10 @@ emacs -batch -l ert -l my-tests.el \ -eval '(ert-run-tests-batch-and-exit "to-match")' @end example +By default, ERT test failure summaries are quite brief in batch +mode--only the names of the failed tests are listed. If the +EMACS_TEST_VERBOSE environment variable is set, the failure summaries +will also include the data from the failing test. @node Test Selectors @section Test Selectors diff --git a/etc/NEWS b/etc/NEWS index 60f3172041..30114cab2f 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2090,6 +2090,13 @@ This allows mode-specific alterations to how 'thing-at-point' works. This is so 'C-a' works as in other modes, and in particular holding Shift while typing 'C-a', i.e. 'C-S-a', will now highlight the text. +** ERT + ++++ +*** ERT can now output more verbose test failure reports. +If the EMACS_TEST_VERBOSE environment variable is set, failure +summaries will include the failing condition. + ** Miscellaneous +++ diff --git a/lisp/emacs-lisp/ert.el b/lisp/emacs-lisp/ert.el index e91ec0af44..6793b374ee 100644 --- a/lisp/emacs-lisp/ert.el +++ b/lisp/emacs-lisp/ert.el @@ -1279,6 +1279,23 @@ EXPECTEDP specifies whether the result was expected." (ert-test-quit '("quit" "QUIT"))))) (elt s (if expectedp 0 1)))) +(defun ert-reason-for-test-result (result) + "Return the reason given for RESULT, as a string. + +The reason is the argument given when invoking `ert-fail' or `ert-skip'. +It is output using `prin1' prefixed by two spaces. + +If no reason was given, or for a successful RESULT, return the +empty string." + (let ((reason + (and + (ert-test-result-with-condition-p result) + (cadr (ert-test-result-with-condition-condition result)))) + (print-escape-newlines t) + (print-level 6) + (print-length 10)) + (if reason (format " %S" reason) ""))) + (defun ert--pp-with-indentation-and-newline (object) "Pretty-print OBJECT, indenting it to the current column of point. Ensures a final newline is inserted." @@ -1369,18 +1386,24 @@ Returns the stats object." (cl-loop for test across (ert--stats-tests stats) for result = (ert-test-most-recent-result test) do (when (not (ert-test-result-expected-p test result)) - (message "%9s %S" + (message "%9s %S%s" (ert-string-for-test-result result nil) - (ert-test-name test)))) + (ert-test-name test) + (if (getenv "EMACS_TEST_VERBOSE") + (ert-reason-for-test-result result) + "")))) (message "%s" "")) (unless (zerop skipped) (message "%s skipped results:" skipped) (cl-loop for test across (ert--stats-tests stats) for result = (ert-test-most-recent-result test) do (when (ert-test-result-type-p result :skipped) - (message "%9s %S" + (message "%9s %S%s" (ert-string-for-test-result result nil) - (ert-test-name test)))) + (ert-test-name test) + (if (getenv "EMACS_TEST_VERBOSE") + (ert-reason-for-test-result result) + "")))) (message "%s" ""))))) (test-started ) commit 81fd5603ce701a0acae096314c1f7ab1db69c64f Author: Lars Ingebrigtsen Date: Tue Jun 15 16:50:51 2021 +0200 Add a new function syntax-class-to-char * doc/lispref/syntax.texi (Syntax Table Internals): Document it. * src/syntax.c (Fsyntax_class_to_char): New function (bug#37452). diff --git a/doc/lispref/syntax.texi b/doc/lispref/syntax.texi index bde7075b0d..deec3f44c0 100644 --- a/doc/lispref/syntax.texi +++ b/doc/lispref/syntax.texi @@ -1047,6 +1047,11 @@ Given a syntax descriptor @var{desc} (a string), this function returns the corresponding raw syntax descriptor. @end defun +@defun syntax-class-to-char syntax +Given a raw syntax descriptor @var{syntax} (an integer), this function +returns the corresponding syntax descriptor (a character). +@end defun + @defun syntax-after pos This function returns the raw syntax descriptor for the character in the buffer after position @var{pos}, taking account of syntax diff --git a/etc/NEWS b/etc/NEWS index 367cd5972a..60f3172041 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -2843,6 +2843,11 @@ customize them. * Lisp Changes in Emacs 28.1 ++++ +** New function 'syntax-class-to-char'. +This does the almost the opposite of 'string-to-syntax' -- it returns +the syntax descriptor (a character) given a raw syntax descriptor. + +++ ** New function 'buffer-local-boundp'. This predicate says whether a symbol is bound in a specific buffer. diff --git a/src/syntax.c b/src/syntax.c index 9fbf88535f..7bba336744 100644 --- a/src/syntax.c +++ b/src/syntax.c @@ -1109,6 +1109,23 @@ this is probably the wrong function to use, because it can't take return make_fixnum (syntax_code_spec[SYNTAX (char_int)]); } +DEFUN ("syntax-class-to-char", Fsyntax_class_to_char, + Ssyntax_class_to_char, 1, 1, 0, + doc: /* Return the syntax char of CLASS, described by an integer. +For example, if SYNTAX is word constituent (the integer 2), the +character `w' (119) is returned. */) + (Lisp_Object syntax) +{ + int syn; + CHECK_FIXNUM (syntax); + syn = XFIXNUM (syntax); + + if (syn < 0 || syn >= sizeof syntax_code_spec) + args_out_of_range (make_fixnum (sizeof syntax_code_spec - 1), + syntax); + return make_fixnum (syntax_code_spec[syn]); +} + DEFUN ("matching-paren", Fmatching_paren, Smatching_paren, 1, 1, 0, doc: /* Return the matching parenthesis of CHARACTER, or nil if none. */) (Lisp_Object character) @@ -3782,6 +3799,7 @@ In both cases, LIMIT bounds the search. */); defsubr (&Scopy_syntax_table); defsubr (&Sset_syntax_table); defsubr (&Schar_syntax); + defsubr (&Ssyntax_class_to_char); defsubr (&Smatching_paren); defsubr (&Sstring_to_syntax); defsubr (&Smodify_syntax_entry); diff --git a/test/src/syntax-tests.el b/test/src/syntax-tests.el index 479b818935..e4e3054d37 100644 --- a/test/src/syntax-tests.el +++ b/test/src/syntax-tests.el @@ -21,6 +21,7 @@ (require 'ert) (require 'ert-x) +(require 'cl-lib) (ert-deftest parse-partial-sexp-continue-over-comment-marker () "Continue a parse that stopped in the middle of a comment marker." @@ -56,6 +57,16 @@ (should (equal (parse-partial-sexp aftC pointX nil nil pps-aftC) ppsX))))) +(ert-deftest syntax-class-character-test () + (cl-loop for char across " .w_()'\"$\\/<>@!|" + for i from 0 + do (should (= char (syntax-class-to-char i))) + when (string-to-syntax (string char)) + do (should (= char (syntax-class-to-char + (car (string-to-syntax (string char))))))) + (should-error (syntax-class-to-char -1)) + (should-error (syntax-class-to-char 200))) + (ert-deftest parse-partial-sexp-paren-comments () "Test syntax parsing with paren comment markers. Specifically, where the first character of the comment marker is commit 53e5caa1bd7363e9eb8f3501dbc7c91928c9c8a3 Author: Filipp Gunbin Date: Tue Jun 15 17:11:51 2021 +0300 ; * doc/lispref/text.texi (Clickable Text): Fix word order diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index c90a95980d..0c87a19fa1 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -4166,7 +4166,7 @@ file names only: If the condition value is anything else, then the position is inside a link and the condition itself is the action code. Clearly, you should specify this kind of condition only when applying the condition via a -text or property overlay on the link text (so that it does not apply +text or overlay property on the link text (so that it does not apply to the entire buffer). @end table commit c62100465e61f0656875716d67c1d7c64248f031 Author: Jared Finder Date: Tue Jun 15 15:54:08 2021 +0200 Fix dragging dividers in terminal Emacs when there's margins * lisp/mouse.el (mouse-drag-line): Do the right thing in the presence of margins (bug#41156). (mouse-drag-line): Bind left-margin/right-margin in the map, too. diff --git a/lisp/mouse.el b/lisp/mouse.el index f4979e37b0..d0064eecfc 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el @@ -415,7 +415,7 @@ must be one of the symbols `header', `mode', or `vertical'." (when (window-live-p (setq posn-window (posn-window start))) ;; Add left edge of `posn-window' to `position'. (setq position (+ (window-pixel-left posn-window) position)) - (unless (nth 1 start) + (unless (posn-area start) ;; Add width of objects on the left of the text area to ;; `position'. (when (eq (window-current-scroll-bars posn-window) 'left) @@ -494,9 +494,11 @@ must be one of the symbols `header', `mode', or `vertical'." (define-key map [header-line] map) (define-key map [vertical-line] map) ;; ... and some maybe even with a right- or bottom-divider - ;; prefix. + ;; or left- or right-margin prefix ... (define-key map [right-divider] map) (define-key map [bottom-divider] map) + (define-key map [left-margin] map) + (define-key map [right-margin] map) map) t (lambda () (setq track-mouse old-track-mouse))))))) commit 17dcc54db4e2c7382eb35a27f880b3936fbaa192 Author: Lars Ingebrigtsen Date: Tue Jun 15 15:46:33 2021 +0200 Document `completions-format' * doc/emacs/mini.texi (Completion Options): Document `completions-format'. * lisp/simple.el (completion-list-mode): Mention in (bug#49003). diff --git a/doc/emacs/mini.texi b/doc/emacs/mini.texi index 2fdb1e7072..6dcee3fa82 100644 --- a/doc/emacs/mini.texi +++ b/doc/emacs/mini.texi @@ -630,6 +630,14 @@ in a cyclic manner. If you give @code{completion-cycle-threshold} a numeric value @var{n}, completion commands switch to this cycling behavior only when there are @var{n} or fewer alternatives. +@vindex completions-format + When displaying completions, Emacs will normally pop up a new buffer +to display the completions. The completions will (by default) be +sorted in columns horizontally in alphabetical order, but this can be +changed by changing the @code{completions-format} user option. If +@code{vertical}, sort the completions vertically in columns instead, +and if @code{one-column}, just use a single column. + @node Minibuffer History @section Minibuffer History @cindex minibuffer history diff --git a/lisp/simple.el b/lisp/simple.el index 4630a11c75..fdaeb6ac22 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -9086,6 +9086,9 @@ Type \\\\[choose-completion] in the completion list\ to select the completion near point. Or click to select one with the mouse. +See the `completions-format' user option to control how this +buffer is formatted. + \\{completion-list-mode-map}") (defun completion-list-mode-finish () commit 1756e4757cee336defa4aea667d0e991737f562c Author: Lars Ingebrigtsen Date: Tue Jun 15 15:33:03 2021 +0200 Fix false positives in docstring width warning with (fn...) constructs. * lisp/emacs-lisp/bytecomp.el (byte-compile--wide-docstring-p): Don't consider the function signature when determining whether the doc string is too wide (bug#49007). (The signature is folded later when displaying help.) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 5ed6bfeddc..472e0ba3ba 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -1635,7 +1635,10 @@ URLs." ;; Ignore these `substitute-command-keys' substitutions. (seq "\\" (or "=" (seq "<" (* (not ">")) ">") - (seq "{" (* (not "}")) "}"))))) + (seq "{" (* (not "}")) "}"))) + ;; Ignore the function signature that's stashed at the end of + ;; the doc string (in some circumstances). + (seq bol "(fn (" (* nonl)))) "" ;; Heuristic: assume these substitutions are of some length N. (replace-regexp-in-string