From 16e9bdff4f47534d62ac9ebec9c6c49fe5a0e180 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 30 Jun 2023 10:13:53 +0300 Subject: [PATCH 1/9] Improve documentation of registers * doc/lispref/text.texi (Registers): Document buffers in registers. Mention "frameset" as another name for "frame configuration". * doc/emacs/regs.texi (Registers, Configuration Registers) (File and Buffer Registers): Clarify and improve wording. Add cross-references and indexing. (Configuration Registers): Rename the section to a more accurate name. (Bug#64354) * lisp/register.el (jump-to-register, point-to-register) (register-alist, frame-configuration-to-register): Doc fixes. (Bug#64353) --- doc/emacs/emacs.texi | 2 +- doc/emacs/regs.texi | 29 ++++++++++++++++++----------- doc/lispref/text.texi | 13 +++++++++---- lisp/register.el | 14 +++++++++----- 4 files changed, 37 insertions(+), 21 deletions(-) diff --git a/doc/emacs/emacs.texi b/doc/emacs/emacs.texi index 7071ea44edd..0efd99261ac 100644 --- a/doc/emacs/emacs.texi +++ b/doc/emacs/emacs.texi @@ -349,7 +349,7 @@ Registers * Position Registers:: Saving positions in registers. * Text Registers:: Saving text in registers. * Rectangle Registers:: Saving rectangles in registers. -* Configuration Registers:: Saving window configurations in registers. +* Configuration Registers:: Saving window/frame configurations in registers. * Number Registers:: Numbers in registers. * File and Buffer Registers:: File and buffer names in registers. * Keyboard Macro Registers:: Keyboard macros in registers. diff --git a/doc/emacs/regs.texi b/doc/emacs/regs.texi index ec2367d71e3..2bc4640cbf4 100644 --- a/doc/emacs/regs.texi +++ b/doc/emacs/regs.texi @@ -22,10 +22,11 @@ because these keys are reserved for quitting (@pxref{Quitting}). @findex view-register A register can store a position, a piece of text, a rectangle, a -number, a window configuration, or a file name, but only one thing at -any given time. Whatever you store in a register remains there until -you store something else in that register. To see what register -@var{r} contains, use @kbd{M-x view-register}: +number, a window or frame configuration, a buffer name, or a file +name, but only one thing at any given time. Whatever you store in a +register remains there until you store something else in that +register. To see what register @var{r} contains, use @kbd{M-x +view-register}: @table @kbd @item M-x view-register @key{RET} @var{r} @@ -50,7 +51,7 @@ this chapter. * Position Registers:: Saving positions in registers. * Text Registers:: Saving text in registers. * Rectangle Registers:: Saving rectangles in registers. -* Configuration Registers:: Saving window configurations in registers. +* Configuration Registers:: Saving window/frame configurations in registers. * Number Registers:: Numbers in registers. * File and Buffer Registers:: File and buffer names in registers. * Keyboard Macro Registers:: Keyboard macros in registers. @@ -182,8 +183,10 @@ previously documented in @ref{Text Registers}, inserts a rectangle rather than a text string, if the register contains a rectangle. @node Configuration Registers -@section Saving Window Configurations in Registers +@section Saving Window and Frame Configurations in Registers @cindex saving window configuration in a register +@cindex saving frame configuration in a register +@cindex frameset, saving in a register @findex window-configuration-to-register @findex frameset-to-register @@ -191,16 +194,17 @@ rather than a text string, if the register contains a rectangle. @kindex C-x r f You can save the window configuration of the selected frame in a register, or even the configuration of all windows in all frames, and -restore the configuration later. @xref{Windows}, for information -about window configurations. +restore the configuration later. @xref{Windows Convenience}, for +information about window configurations. @table @kbd @item C-x r w @var{r} Save the state of the selected frame's windows in register @var{r} (@code{window-configuration-to-register}). +@cindex frameset @item C-x r f @var{r} -Save the state of all frames, including all their windows, in register -@var{r} (@code{frameset-to-register}). +Save the state of all frames, including all their windows (a.k.a.@: +@dfn{frameset}), in register @var{r} (@code{frameset-to-register}). @end table Use @kbd{C-x r j @var{r}} to restore a window or frame configuration. @@ -266,7 +270,7 @@ puts the file name shown in register @samp{z}. @var{r}}. (This is the same command used to jump to a position or restore a frame configuration.) - Similarly, if there's certain buffers you visit frequently, you + Similarly, if there are certain buffers you visit frequently, you can put their names in registers. For instance, if you visit the @samp{*Messages*} buffer often, you can use the following snippet to put that buffer into the @samp{m} register: @@ -275,6 +279,9 @@ put that buffer into the @samp{m} register: (set-register ?m '(buffer . "*Messages*")) @end smallexample + To switch to the buffer whose name is in register @var{r}, type +@kbd{C-x r j @var{r}}. + @node Keyboard Macro Registers @section Keyboard Macro Registers @cindex saving keyboard macro in a register diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 0f43f3d464a..af6d6638b36 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -4642,20 +4642,25 @@ A rectangle is represented by a list of strings. This represents a window configuration to restore in one frame, and a position to jump to in the current buffer. -@c FIXME: Mention frameset here. +@cindex frameset @item @code{(@var{frame-configuration} @var{position})} This represents a frame configuration to restore, and a position -to jump to in the current buffer. +to jump to in the current buffer. Frame configurations are also +known as @dfn{framesets}. -@item (file @var{filename}) +@item @code{(file @var{filename})} This represents a file to visit; jumping to this value visits file @var{filename}. -@item (file-query @var{filename} @var{position}) +@item @code{(file-query @var{filename} @var{position})} This represents a file to visit and a position in it; jumping to this value visits file @var{filename} and goes to buffer position @var{position}. Restoring this type of position asks the user for confirmation first. + +@item @code{(buffer @var{buffer-name})} +This represents a buffer; jumping to this value switches to buffer +@var{buffer-name}. @end table The functions in this section return unpredictable values unless diff --git a/lisp/register.el b/lisp/register.el index d30114bfbc7..667e03418bd 100644 --- a/lisp/register.el +++ b/lisp/register.el @@ -69,10 +69,12 @@ A list of the form (file . FILE-NAME) represents the file named FILE-NAME. A list of the form (file-query FILE-NAME POSITION) represents position POSITION in the file named FILE-NAME, but query before visiting it. +A list of the form (buffer . BUFFER-NAME) represents the buffer BUFFER-NAME. A list of the form (WINDOW-CONFIGURATION POSITION) represents a saved window configuration plus a saved value of point. A list of the form (FRAME-CONFIGURATION POSITION) - represents a saved frame configuration plus a saved value of point.") + represents a saved frame configuration (a.k.a. \"frameset\") plus + a saved value of point.") (defgroup register nil "Register commands." @@ -179,7 +181,7 @@ display such a window regardless." (defun point-to-register (register &optional arg) "Store current location of point in register REGISTER. -With prefix argument, store current frame configuration. +With prefix argument, store current frame configuration (a.k.a. \"frameset\"). Use \\[jump-to-register] to go to that location or restore that configuration. Argument is a character, naming the register. @@ -214,6 +216,7 @@ Interactively, reads the register using `register-read-with-preview'." (defun frame-configuration-to-register (register &optional _arg) "Store the window configuration of all frames in register REGISTER. +\(This window configuration is also known as \"frameset\"). Use \\[jump-to-register] to restore the configuration. Argument is a character, naming the register. @@ -240,9 +243,10 @@ If the register contains a file name, find that file. If the register contains a window configuration (one frame) or a frameset \(all frames), restore that frame or all frames accordingly. First argument is a character, naming the register. -Optional second arg non-nil (interactively, prefix argument) says to -delete any existing frames that the frameset doesn't mention. -\(Otherwise, these frames are iconified.) +Optional second arg DELETE non-nil (interactively, prefix argument) says +to delete any existing frames that the frameset doesn't mention. +\(Otherwise, these frames are iconified.) This argument is currently +ignored if the register contains anything but a frameset. Interactively, reads the register using `register-read-with-preview'." (interactive (list (register-read-with-preview "Jump to register: ") From 624c779517d0743deaf97145e7c577805730d9da Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" Date: Fri, 30 Jun 2023 11:58:33 +0100 Subject: [PATCH 2/9] ; Fix tree-sitter C binding typos in Elisp manual. --- doc/lispref/parsing.texi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi index 9e1df07d25c..353585f79c7 100644 --- a/doc/lispref/parsing.texi +++ b/doc/lispref/parsing.texi @@ -1921,7 +1921,7 @@ ts_node_field_name_for_child treesit-node-field-name-for-child ts_node_child_count treesit-node-child-count ts_node_named_child treesit-node-child ts_node_named_child_count treesit-node-child-count -ts_node_child_by_field_name treesit-node-by-field-name +ts_node_child_by_field_name treesit-node-child-by-field-name ts_node_child_by_field_id ts_node_next_sibling treesit-node-next-sibling ts_node_prev_sibling treesit-node-prev-sibling @@ -1929,9 +1929,9 @@ ts_node_next_named_sibling treesit-node-next-sibling ts_node_prev_named_sibling treesit-node-prev-sibling ts_node_first_child_for_byte treesit-node-first-child-for-pos ts_node_first_named_child_for_byte treesit-node-first-child-for-pos -ts_node_descendant_for_byte_range treesit-descendant-for-range +ts_node_descendant_for_byte_range treesit-node-descendant-for-range ts_node_descendant_for_point_range -ts_node_named_descendant_for_byte_range treesit-descendant-for-range +ts_node_named_descendant_for_byte_range treesit-node-descendant-for-range ts_node_named_descendant_for_point_range ts_node_edit ts_node_eq treesit-node-eq From 0be18d80978ff873f8c93c7b84b1bd31ca5887c8 Mon Sep 17 00:00:00 2001 From: "Basil L. Contovounesios" Date: Fri, 30 Jun 2023 12:21:00 +0100 Subject: [PATCH 3/9] ; Fix @xref in last change to doc/emacs/regs.texi. --- doc/emacs/regs.texi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/emacs/regs.texi b/doc/emacs/regs.texi index 2bc4640cbf4..e52f68dd18e 100644 --- a/doc/emacs/regs.texi +++ b/doc/emacs/regs.texi @@ -194,7 +194,7 @@ rather than a text string, if the register contains a rectangle. @kindex C-x r f You can save the window configuration of the selected frame in a register, or even the configuration of all windows in all frames, and -restore the configuration later. @xref{Windows Convenience}, for +restore the configuration later. @xref{Window Convenience}, for information about window configurations. @table @kbd From a5bd9fb8c4a4d96e20b05557128448a48cff36c7 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Fri, 30 Jun 2023 14:47:12 +0300 Subject: [PATCH 4/9] ; Improve doc strings in register.el * lisp/register.el (register-preview-delay) (register-describe-oneline, register-preview-default) (register-preview-function, register-preview, point-to-register) (window-configuration-to-register) (frame-configuration-to-register, jump-to-register) (register-val-jump-to, number-to-register, increment-register) (view-register, list-registers, register-val-describe) (insert-register, register-val-insert, copy-to-register) (append-to-register, prepend-to-register) (copy-rectangle-to-register): Doc fixes. --- lisp/register.el | 136 ++++++++++++++++++++++++++--------------------- 1 file changed, 76 insertions(+), 60 deletions(-) diff --git a/lisp/register.el b/lisp/register.el index 667e03418bd..56ab089efb7 100644 --- a/lisp/register.el +++ b/lisp/register.el @@ -92,7 +92,7 @@ of the marked text." (character :tag "Use register" :value ?+))) (defcustom register-preview-delay 1 - "If non-nil, time to wait in seconds before popping up a preview window. + "If non-nil, time to wait in seconds before popping up register preview window. If nil, do not show register previews, unless `help-char' (or a member of `help-event-list') is pressed." :version "24.4" @@ -109,7 +109,7 @@ See the documentation of the variable `register-alist' for possible VALUEs." (setf (alist-get register register-alist) value)) (defun register-describe-oneline (c) - "One-line description of register C." + "Return a one-line description of register C." (let ((d (replace-regexp-in-string "\n[ \t]*" " " (with-output-to-string (describe-register-1 c))))) @@ -118,19 +118,19 @@ See the documentation of the variable `register-alist' for possible VALUEs." d))) (defun register-preview-default (r) - "Default function for the variable `register-preview-function'." + "Function that is the default value of the variable `register-preview-function'." (format "%s: %s\n" (single-key-description (car r)) (register-describe-oneline (car r)))) (defvar register-preview-function #'register-preview-default "Function to format a register for previewing. -Takes one argument, a cons (NAME . CONTENTS) as found in `register-alist'. -Returns a string.") +Called with one argument, a cons (NAME . CONTENTS) as found in `register-alist'. +The function should return a string, the description of teh argument.") (defun register-preview (buffer &optional show-empty) - "Pop up a window to show register preview in BUFFER. -If SHOW-EMPTY is non-nil show the window even if no registers. + "Pop up a window showing the registers preview in BUFFER. +If SHOW-EMPTY is non-nil, show the window even if no registers. Format of each entry is controlled by the variable `register-preview-function'." (when (or show-empty (consp register-alist)) (with-current-buffer-window @@ -180,12 +180,12 @@ display such a window regardless." (and (get-buffer buffer) (kill-buffer buffer))))) (defun point-to-register (register &optional arg) - "Store current location of point in register REGISTER. -With prefix argument, store current frame configuration (a.k.a. \"frameset\"). + "Store current location of point in REGISTER. +With prefix argument ARG, store current frame configuration (a.k.a. \"frameset\"). Use \\[jump-to-register] to go to that location or restore that configuration. -Argument is a character, naming the register. +Argument is a character, the name of the register. -Interactively, reads the register using `register-read-with-preview'." +Interactively, prompt for REGISTER using `register-read-with-preview'." (interactive (list (register-read-with-preview (if current-prefix-arg "Frame configuration to register: " @@ -198,11 +198,11 @@ Interactively, reads the register using `register-read-with-preview'." (point-marker)))) (defun window-configuration-to-register (register &optional _arg) - "Store the window configuration of the selected frame in register REGISTER. + "Store the window configuration of the selected frame in REGISTER. Use \\[jump-to-register] to restore the configuration. -Argument is a character, naming the register. +Argument is a character, the name of the register. -Interactively, reads the register using `register-read-with-preview'." +Interactively, prompt for REGISTER using `register-read-with-preview'." (interactive (list (register-read-with-preview "Window configuration to register: ") current-prefix-arg)) @@ -215,12 +215,12 @@ Interactively, reads the register using `register-read-with-preview'." '(register) "24.4") (defun frame-configuration-to-register (register &optional _arg) - "Store the window configuration of all frames in register REGISTER. + "Store the window configurations of all frames in REGISTER. \(This window configuration is also known as \"frameset\"). Use \\[jump-to-register] to restore the configuration. -Argument is a character, naming the register. +Argument is a character, the name of the register. -Interactively, reads the register using `register-read-with-preview'." +Interactively, prompt for REGISTER using `register-read-with-preview'." (interactive (list (register-read-with-preview "Frame configuration to register: ") current-prefix-arg)) @@ -236,19 +236,21 @@ Interactively, reads the register using `register-read-with-preview'." (defalias 'register-to-point 'jump-to-register) (defun jump-to-register (register &optional delete) - "Move point to location stored in a register. -Push the mark if jumping moves point, unless called in succession. + "Go to location stored in REGISTER, or restore configuration stored there. +Push the mark if going to the location moves point, unless called in succession. If the register contains a file name, find that file. -\(To put a file name in a register, you must use `set-register'.) +If the register contains a buffer name, switch to that buffer. +\(To put a file or buffer name in a register, you must use `set-register'.) If the register contains a window configuration (one frame) or a frameset -\(all frames), restore that frame or all frames accordingly. -First argument is a character, naming the register. +\(all frames), restore the configuration of that frame or of all frames +accordingly. +First argument REGISTER is a character, the name of the register. Optional second arg DELETE non-nil (interactively, prefix argument) says to delete any existing frames that the frameset doesn't mention. \(Otherwise, these frames are iconified.) This argument is currently ignored if the register contains anything but a frameset. -Interactively, reads the register using `register-read-with-preview'." +Interactively, prompt for REGISTER using `register-read-with-preview'." (interactive (list (register-read-with-preview "Jump to register: ") current-prefix-arg)) (let ((val (get-register register))) @@ -256,6 +258,7 @@ Interactively, reads the register using `register-read-with-preview'." (cl-defgeneric register-val-jump-to (_val _arg) "Execute the \"jump\" operation of VAL. +VAL is the contents of a register as returned by `get-register'. ARG is the value of the prefix argument or nil." (user-error "Register doesn't contain a buffer position or configuration")) @@ -305,13 +308,13 @@ ARG is the value of the prefix argument or nil." (marker-position (cdr elem)))))))) (defun number-to-register (number register) - "Store a number in a register. -Two args, NUMBER and REGISTER (a character, naming the register). -If NUMBER is nil, a decimal number is read from the buffer starting + "Store NUMBER in REGISTER. +REGISTER is a character, the name of the register. +If NUMBER is nil, a decimal number is read from the buffer at point, and point moves to the end of that number. Interactively, NUMBER is the prefix arg (none means nil). -Interactively, reads the register using `register-read-with-preview'." +Interactively, prompt for REGISTER using `register-read-with-preview'." (interactive (list current-prefix-arg (register-read-with-preview "Number to register: "))) (set-register register @@ -324,8 +327,8 @@ Interactively, reads the register using `register-read-with-preview'." 0)))) (defun increment-register (prefix register) - "Augment contents of REGISTER. -Interactively, PREFIX is in raw form. + "Augment contents of REGISTER using PREFIX. +Interactively, PREFIX is the raw prefix argument. If REGISTER contains a number, add `prefix-numeric-value' of PREFIX to it. @@ -333,7 +336,7 @@ PREFIX to it. If REGISTER is empty or if it contains text, call `append-to-register' with `delete-flag' set to PREFIX. -Interactively, reads the register using `register-read-with-preview'." +Interactively, prompt for REGISTER using `register-read-with-preview'." (interactive (list current-prefix-arg (register-read-with-preview "Increment register: "))) (let ((register-val (get-register register))) @@ -346,10 +349,10 @@ Interactively, reads the register using `register-read-with-preview'." (t (user-error "Register does not contain a number or text"))))) (defun view-register (register) - "Display what is contained in register named REGISTER. -The Lisp value REGISTER is a character. + "Display the description of the contents of REGISTER. +REGISTER is a character, the name of the register. -Interactively, reads the register using `register-read-with-preview'." +Interactively, prompt for REGISTER using `register-read-with-preview'." (interactive (list (register-read-with-preview "View register: "))) (let ((val (get-register register))) (if (null val) @@ -358,7 +361,7 @@ Interactively, reads the register using `register-read-with-preview'." (describe-register-1 register t))))) (defun list-registers () - "Display a list of nonempty registers saying briefly what they contain." + "Display the list of nonempty registers with brief descriptions of contents." (interactive) (let ((list (copy-sequence register-alist))) (setq list (sort list (lambda (a b) (< (car a) (car b))))) @@ -376,7 +379,10 @@ Interactively, reads the register using `register-read-with-preview'." (register-val-describe val verbose))) (cl-defgeneric register-val-describe (val verbose) - "Print description of register value VAL to `standard-output'." + "Print description of register value VAL to `standard-output'. +Second argument VERBOSE is ignored, unless VAL is not one of the +supported kinds of register contents, in which case it is displayed +using `prin1'." (princ "Garbage:\n") (if verbose (prin1 val))) @@ -471,13 +477,14 @@ Interactively, reads the register using `register-read-with-preview'." (princ "the empty string"))))) (defun insert-register (register &optional arg) - "Insert contents of register REGISTER. (REGISTER is a character.) -Normally puts point before and mark after the inserted text. -If optional second arg is non-nil, puts mark before and point after. -Interactively, second arg is nil if prefix arg is supplied and t -otherwise. + "Insert contents of REGISTER at point. +REGISTER is a character, the name of the register. +Normally puts point before and mark after the inserted text, but +if optional second argument ARG is non-nil, puts mark before and +point after. Interactively, ARG is nil if prefix arg is supplied, +and t otherwise. -Interactively, reads the register using `register-read-with-preview'." +Interactively, prompt for REGISTER using `register-read-with-preview'." (interactive (progn (barf-if-buffer-read-only) (list (register-read-with-preview "Insert register: ") @@ -488,7 +495,7 @@ Interactively, reads the register using `register-read-with-preview'." (if (not arg) (exchange-point-and-mark))) (cl-defgeneric register-val-insert (_val) - "Insert register value VAL." + "Insert register value VAL in current buffer at point." (user-error "Register does not contain text")) (cl-defmethod register-val-insert ((val registerv)) @@ -511,14 +518,17 @@ Interactively, reads the register using `register-read-with-preview'." (cl-call-next-method val))) (defun copy-to-register (register start end &optional delete-flag region) - "Copy region into register REGISTER. -With prefix arg, delete as well. -Called from program, takes five args: REGISTER, START, END, DELETE-FLAG, + "Copy region of text between START and END into REGISTER. +If DELETE-FLAG is non-nil (interactively, prefix arg), delete the region +after copying. +Called from Lisp, takes five args: REGISTER, START, END, DELETE-FLAG, and REGION. START and END are buffer positions indicating what to copy. -The optional argument REGION if non-nil, indicates that we're not just -copying some text between START and END, but we're copying the region. +The optional argument REGION, if non-nil, means START..END denotes the +region. -Interactively, reads the register using `register-read-with-preview'." +Interactively, prompt for REGISTER using `register-read-with-preview' +and use mark and point as START and END; REGION is always non-nil in +this case." (interactive (list (register-read-with-preview "Copy to register: ") (region-beginning) (region-end) @@ -534,12 +544,14 @@ Interactively, reads the register using `register-read-with-preview'." (indicate-copied-region)))) (defun append-to-register (register start end &optional delete-flag) - "Append region to text in register REGISTER. -With prefix arg, delete as well. -Called from program, takes four args: REGISTER, START, END and DELETE-FLAG. + "Append region of text between START and END to REGISTER. +If DELETE-FLAG is non-nil (interactively, prefix arg), delete the region +after appending. +Called from Lisp, takes four args: REGISTER, START, END and DELETE-FLAG. START and END are buffer positions indicating what to append. -Interactively, reads the register using `register-read-with-preview'." +Interactively, prompt for REGISTER using `register-read-with-preview', +and use mark and point as START and END." (interactive (list (register-read-with-preview "Append to register: ") (region-beginning) (region-end) @@ -558,12 +570,14 @@ Interactively, reads the register using `register-read-with-preview'." (indicate-copied-region)))) (defun prepend-to-register (register start end &optional delete-flag) - "Prepend region to text in register REGISTER. -With prefix arg, delete as well. + "Prepend region of text between START and END to REGISTER. +If DELETE-FLAG is non-nil (interactively, prefix arg), delete the region +after prepending. Called from program, takes four args: REGISTER, START, END and DELETE-FLAG. START and END are buffer positions indicating what to prepend. -Interactively, reads the register using `register-read-with-preview'." +Interactively, prompt for REGISTER using `register-read-with-preview', +and use mark and point as START and END." (interactive (list (register-read-with-preview "Prepend to register: ") (region-beginning) (region-end) @@ -582,14 +596,16 @@ Interactively, reads the register using `register-read-with-preview'." (indicate-copied-region)))) (defun copy-rectangle-to-register (register start end &optional delete-flag) - "Copy rectangular region into register REGISTER. -With prefix arg, delete as well. -To insert this register in the buffer, use \\[insert-register]. + "Copy rectangular region of text between START and END into REGISTER. +If DELETE-FLAG is non-nil (interactively, prefix arg), delete the region +after copying. +To insert this register into a buffer, use \\[insert-register]. -Called from a program, takes four args: REGISTER, START, END and DELETE-FLAG. +Called from Lisp, takes four args: REGISTER, START, END and DELETE-FLAG. START and END are buffer positions giving two corners of rectangle. -Interactively, reads the register using `register-read-with-preview'." +Interactively, prompt for REGISTER using `register-read-with-preview', +and use mark and point as START and END." (interactive (list (register-read-with-preview "Copy rectangle to register: ") (region-beginning) From cc660bd265172ffd75851d418db9af66704d0e54 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 1 Jul 2023 10:01:59 +0300 Subject: [PATCH 5/9] ; * etc/PROBLEMS: Mention MinGW problems with -D_FORTIFY_SOURCE=2. --- etc/PROBLEMS | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/etc/PROBLEMS b/etc/PROBLEMS index cdce8bbc774..30769e68f11 100644 --- a/etc/PROBLEMS +++ b/etc/PROBLEMS @@ -2768,6 +2768,21 @@ With any of the above methods, you'd need to restart Emacs (and preferably also your Windows system) after making the changes, to have them take effect. +*** MinGW64 Emacs built with -D_FORTIFY_SOURCE=2 misbehaves + +Using this preprocessor option when building Emacs with MinGW64 +produces an Emacs binary that behaves incorrectly. In particular, +running asynchronous shell command, e.g., with 'M-&', causes Emacs to +use 100% of CPU and start allocating a lot of memory. For the same +reason, asynchronous native-compilation will hang Emacs (which could +wedge Emacs during startup, if your Emacs is configured to download +and install packages via package.el every startup). 'M-x run-python', +'M-x shell', and similar commands also hang. Other commands might +also cause high CPU and/or memory usage. + +The workaround is to rebuild Emacs without the -D_FORTIFY_SOURCE=2 +option. + ** Emacs on Windows 9X requires UNICOWS.DLL If that DLL is not available, Emacs will display an error dialog From fc6099bf04696b01eaa21c9948a8d8d91345a66c Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 1 Jul 2023 12:28:33 +0300 Subject: [PATCH 6/9] ; Improve documentation of text-property-search-* functions * doc/lispref/text.texi (Property Search): Improve wording and markup. * lisp/emacs-lisp/text-property-search.el (text-property-search-forward) (text-property-search-backward): Doc fixes. (Bug#64367) --- doc/lispref/text.texi | 51 ++++++++++++++----------- lisp/emacs-lisp/text-property-search.el | 35 ++++++++--------- 2 files changed, 47 insertions(+), 39 deletions(-) diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index af6d6638b36..342e23beadb 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -3398,37 +3398,43 @@ for @var{object} is the current buffer. @end defun @defun text-property-search-forward prop &optional value predicate not-current -Search for the next region that has text property @var{prop} set to -@var{value} according to @var{predicate}. +Search for the next region of text whose property @var{prop} is a +match for @var{value} (which defaults to @code{nil}), according to +@var{predicate}. -This function is modeled after @code{search-forward} and friends in -that it moves point, but it returns a structure that describes the -match instead of returning it in @code{match-beginning} and friends. +This function is modeled after @code{search-forward} (@pxref{String +Search}) and friends, in that it moves point, but it also returns a +structure that describes the match instead of returning it in +@code{match-beginning} and friends. -If the text property can't be found, the function returns @code{nil}. -If it's found, point is placed at the end of the region that has this -text property match, and a @code{prop-match} structure is returned. +If the text property whose value is a match can't be found, the +function returns @code{nil}. If it's found, point is placed at the +end of the region that has this matching text property, and the +function returns a @code{prop-match} structure with information about +the match. @var{predicate} can either be @code{t} (which is a synonym for @code{equal}), @code{nil} (which means ``not equal''), or a predicate -that will be called with two parameters: The first is @var{value}, and -the second is the value of the text property we're inspecting. +that will be called with two arguments: @var{value} and the value of +the text property @var{prop} at the buffer position that is a +candidate for a match. The function should return non-@code{nil} if +there's a match, @code{nil} otherwise. -If @var{not-current}, if point is in a region where we have a match, -then skip past that and find the next instance instead. +If @var{not-current} is non-@code{nil}, then if point is already in a +region where we have a property match, skip past that region and find +the next region instead. -The @code{prop-match} structure has the following accessors: +The @code{prop-match} structure has the following accessor functionss: @code{prop-match-beginning} (the start of the match), @code{prop-match-end} (the end of the match), and @code{prop-match-value} (the value of @var{property} at the start of the match). -In the examples below, imagine that you're in a buffer that looks like -this: +In the examples below, we use a buffer whose contents is: -@example -This is a bold and here's bolditalic and this is the end. -@end example +@display +This is a @b{bold} and here's @b{@i{bolditalic}} and this is the end. +@end display That is, the ``bold'' words are the @code{bold} face, and the ``italic'' word is in the @code{italic} face. @@ -3452,8 +3458,9 @@ This will pick out all the words that use the @code{bold} face. @end lisp This will pick out all the bits that have no face properties, which -will result in the list @samp{("This is a " "and here's " "and this is -the end")} (only reversed, since we used @code{push}). +will result in the list @samp{(@w{"This is a "} @w{"and here's "} +@w{"and this is the end"})} (only in reverse order, since we used +@code{push}, @pxref{List Variables}). @lisp (while (setq match (text-property-search-forward 'face nil nil)) @@ -3481,8 +3488,8 @@ This will give you a list of all those URLs. @defun text-property-search-backward prop &optional value predicate not-current This is just like @code{text-property-search-forward}, but searches -backward instead. Point is placed at the beginning of the matched -region instead of the end, though. +backward instead, and if a match is found, point is placed at the +beginning of the matched region instead of the end. @end defun diff --git a/lisp/emacs-lisp/text-property-search.el b/lisp/emacs-lisp/text-property-search.el index 920278b903a..669cdd97319 100644 --- a/lisp/emacs-lisp/text-property-search.el +++ b/lisp/emacs-lisp/text-property-search.el @@ -31,40 +31,41 @@ (defun text-property-search-forward (property &optional value predicate not-current) - "Search for the next region of text where PREDICATE is true. -PREDICATE is used to decide whether a value of PROPERTY should be -considered as matching VALUE. + "Search for next region of text where PREDICATE returns non-nil for PROPERTY. +PREDICATE is used to decide whether the value of PROPERTY at a given +buffer position should be considered as a match for VALUE. +VALUE defaults to nil if omitted. If PREDICATE is a function, it will be called with two arguments: -VALUE and the value of PROPERTY. The function should return -non-nil if these two values are to be considered a match. +VALUE and the value of PROPERTY at some buffer position. The function +should return non-nil if these two values are to be considered a match. Two special values of PREDICATE can also be used: -If PREDICATE is t, that means a value must `equal' VALUE to be -considered a match. -If PREDICATE is nil (which is the default value), a value will -match if is not `equal' to VALUE. Furthermore, a nil PREDICATE -means that the match region is ended if the value changes. For +If PREDICATE is t, that means the value of PROPERTY must `equal' VALUE +to be considered a match. +If PREDICATE is nil (which is the default), the value of PROPERTY will +match if it is not `equal' to VALUE. Furthermore, a nil PREDICATE +means that the match region ends where the value changes. For instance, this means that if you loop with (while (setq prop (text-property-search-forward \\='face)) ...) -you will get all distinct regions with non-nil `face' values in +you will get all the distinct regions with non-nil `face' values in the buffer, and the `prop' object will have the details about the match. See the manual for more details and examples about how VALUE and PREDICATE interact. -If NOT-CURRENT is non-nil, the function will search for the first -region that doesn't include point and has a value of PROPERTY -that matches VALUE. +If NOT-CURRENT is non-nil, current buffer position is not examined for +matches: the function will search for the first region that doesn't +include point and has a value of PROPERTY that matches VALUE. If no matches can be found, return nil and don't move point. If found, move point to the end of the region and return a `prop-match' object describing the match. To access the details of the match, use `prop-match-beginning' and `prop-match-end' for -the buffer positions that limit the region, and -`prop-match-value' for the value of PROPERTY in the region." +the buffer positions that limit the region, and `prop-match-value' +for the value of PROPERTY in the region." (interactive (list (let ((string (completing-read "Search for property: " obarray))) @@ -134,7 +135,7 @@ the buffer positions that limit the region, and (defun text-property-search-backward (property &optional value predicate not-current) - "Search for the previous region of text whose PROPERTY matches VALUE. + "Search for previous region of text where PREDICATE returns non-nil for PROPERTY. Like `text-property-search-forward', which see, but searches backward, and if a matching region is found, place point at the start of the region." From ab8d0f7b7688d103be71072ea16a4d153806ef50 Mon Sep 17 00:00:00 2001 From: Spencer Baugh Date: Mon, 15 May 2023 14:01:32 -0400 Subject: [PATCH 7/9] Add project command entries to the menu-bar This will make it easier for new users to learn these increasingly important and useful commands. (Bug#63469) * lisp/menu-bar.el (menu-bar-file-menu): Add project-dired and project-find-file entries. (menu-bar-search-menu): Add project-find-regexp entry. (menu-bar-replace-menu): Add project-query-replace regexp entry. (menu-bar-shell-commands-menu): Add project-shell entry. (menu-bar-buffers-menu-command-entries): Add project-switch-to-buffer and project-list-buffer entries. (menu-bar-project-menu): Add. (menu-bar-tools-menu): Add "Project" submenu, and also project-compile entry and change text for compile entry. --- lisp/menu-bar.el | 66 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 3 deletions(-) diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index f6b87d1078d..ac41a11379a 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -219,10 +219,18 @@ '(menu-item "Insert File..." insert-file :enable (menu-bar-non-minibuffer-window-p) :help "Insert another file into current buffer")) + (bindings--define-key menu [project-dired] + '(menu-item "Open Project Directory" project-dired + :enable (menu-bar-non-minibuffer-window-p) + :help "Read the root directory of the current project, to operate on its files")) (bindings--define-key menu [dired] '(menu-item "Open Directory..." dired :enable (menu-bar-non-minibuffer-window-p) :help "Read a directory, to operate on its files")) + (bindings--define-key menu [project-open-file] + '(menu-item "Open File In Project..." project-find-file + :enable (menu-bar-non-minibuffer-window-p) + :help "Read an existing file in the current project into an Emacs buffer")) (bindings--define-key menu [open-file] '(menu-item "Open File..." menu-find-file-existing :enable (menu-bar-non-minibuffer-window-p) @@ -347,6 +355,9 @@ (bindings--define-key menu [tags-srch] '(menu-item "Search Tagged Files..." tags-search :help "Search for a regexp in all tagged files")) + (bindings--define-key menu [project-search] + '(menu-item "Search in Project Files..." project-find-regexp + :help "Search for a regexp in files of the current project")) (bindings--define-key menu [separator-tag-search] menu-bar-separator) (bindings--define-key menu [repeat-search-back] @@ -398,6 +409,9 @@ (bindings--define-key menu [tags-repl] '(menu-item "Replace in Tagged Files..." tags-query-replace :help "Interactively replace a regexp in all tagged files")) + (bindings--define-key menu [project-replace] + '(menu-item "Replace in Project Files..." project-query-replace-regexp + :help "Interactively replace a regexp in files of the current project")) (bindings--define-key menu [separator-replace-tags] menu-bar-separator) @@ -1746,8 +1760,12 @@ mail status in mode line")) (defvar menu-bar-shell-commands-menu (let ((menu (make-sparse-keymap "Shell Commands"))) + (bindings--define-key menu [project-interactive-shell] + '(menu-item "Run Shell In Project" project-shell + :help "Run a subshell interactively, in the current project's root directory")) + (bindings--define-key menu [interactive-shell] - '(menu-item "Run Shell Interactively" shell + '(menu-item "Run Shell" shell :help "Run a subshell interactively")) (bindings--define-key menu [async-shell-command] @@ -1765,6 +1783,31 @@ mail status in mode line")) menu)) +(defvar menu-bar-project-menu + (let ((menu (make-sparse-keymap "Project"))) + (bindings--define-key menu [project-execute-extended-command] '(menu-item "Execute Extended Command..." project-execute-extended-command :help "Execute an extended command in project root")) + (bindings--define-key menu [project-query-replace-regexp] '(menu-item "Query Replace Regexp..." project-query-replace-regexp :help "Interactively replace a regexp in files of the current project")) + (bindings--define-key menu [project-or-external-find-regexp] '(menu-item "Find Regexp Including External Roots..." project-or-external-find-regexp :help "Search for a regexp in files of the current project or external files")) + (bindings--define-key menu [project-find-regexp] '(menu-item "Find Regexp..." project-find-regexp :help "Search for a regexp in files of the current project")) + (bindings--define-key menu [separator-project-search] menu-bar-separator) + (bindings--define-key menu [project-kill-buffers] '(menu-item "Kill Buffers..." project-kill-buffers :help "Kill the buffers belonging to the current project")) + (bindings--define-key menu [project-list-buffers] '(menu-item "List Buffers..." project-list-buffers :help "Pop up a window listing all Emacs buffers in the current project")) + (bindings--define-key menu [project-switch-to-buffer] '(menu-item "Switch To Buffer..." project-switch-to-buffer :help "Prompt for a buffer in the current project, and switch to it")) + (bindings--define-key menu [separator-project-buffers] menu-bar-separator) + (bindings--define-key menu [project-async-shell-command] '(menu-item "Async Shell Command..." project-async-shell-command :help "Invoke a shell command in project root asynchronously in background")) + (bindings--define-key menu [project-shell-command] '(menu-item "Shell Command..." project-shell-command :help "Invoke a shell command in project root and catch its output")) + (bindings--define-key menu [project-eshell] '(menu-item "Run Eshell" project-eshell :help "Run eshell for the current project")) + (bindings--define-key menu [project-shell] '(menu-item "Run Shell" project-shell :help "Run a subshell interactively, in the current project's root directory")) + (bindings--define-key menu [project-compile] '(menu-item "Compile..." project-compile :help "Invoke compiler or Make for current project, view errors")) + (bindings--define-key menu [separator-project-programs] menu-bar-separator) + (bindings--define-key menu [project-switch-project] '(menu-item "Switch Project..." project-switch-project :help "Switch to another project and then run a command")) + (bindings--define-key menu [project-vc-dir] '(menu-item "VC Dir..." project-vc-dir :help "Show the VC status of the project repository")) + (bindings--define-key menu [project-dired] '(menu-item "Open Project Root" project-dired :help "Read the root directory of the current project, to operate on its files")) + (bindings--define-key menu [project-find-dir] '(menu-item "Open Directory..." project-find-dir :help "Open an existing directory in the current project")) + (bindings--define-key menu [project-or-external-find-file] '(menu-item "Open File Including External Roots..." project-or-external-find-file :help "Open an existing file in the current project or its external roots")) + (bindings--define-key menu [project-open-file] '(menu-item "Open File..." project-find-file :help "Open an existing file in the current project")) + menu)) + (defun menu-bar-read-mail () "Read mail using `read-mail-command'." (interactive) @@ -1851,6 +1894,9 @@ mail status in mode line")) '(menu-item "Language Server Support (Eglot)" eglot :help "Start language server suitable for this buffer's major-mode")) + (bindings--define-key menu [project] + `(menu-item "Project" ,menu-bar-project-menu)) + (bindings--define-key menu [ede] '(menu-item "Project Support (EDE)" global-ede-mode @@ -1860,9 +1906,13 @@ mail status in mode line")) (bindings--define-key menu [gdb] '(menu-item "Debugger (GDB)..." gdb :help "Debug a program from within Emacs with GDB")) + (bindings--define-key menu [project-compile] + '(menu-item "Compile Project..." project-compile + :help "Invoke compiler or Make for current project, view errors")) + (bindings--define-key menu [compile] '(menu-item "Compile..." compile - :help "Invoke compiler or Make, view compilation errors")) + :help "Invoke compiler or Make in current buffer's directory, view errors")) (bindings--define-key menu [shell-commands] `(menu-item "Shell Commands" @@ -2347,7 +2397,17 @@ Buffers menu is regenerated." 'menu-item "List All Buffers" 'list-buffers - :help "Pop up a window listing all Emacs buffers")) + :help "Pop up a window listing all Emacs buffers") + (list 'select-buffer-in-project + 'menu-item + "Select Buffer In Project..." + 'project-switch-to-buffer + :help "Prompt for a buffer in the current project, and switch to it") + (list 'list-buffers-in-project + 'menu-item + "List Buffers In Project..." + 'project-list-buffers + :help "Pop up a window listing all Emacs buffers in the current project")) "Entries to be included at the end of the \"Buffers\" menu.") (defvar menu-bar-select-buffer-function 'switch-to-buffer From 16eac20a5db6952564b177263e27c90cb083d335 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 1 Jul 2023 12:43:33 +0300 Subject: [PATCH 8/9] ; Fix last change * lisp/menu-bar.el (menu-bar-file-menu, menu-bar-search-menu) (menu-bar-replace-menu, menu-bar-project-menu) (menu-bar-buffers-menu-command-entries): Fix help-echo text (bug#63469). --- lisp/menu-bar.el | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/lisp/menu-bar.el b/lisp/menu-bar.el index ac41a11379a..21785e43a6e 100644 --- a/lisp/menu-bar.el +++ b/lisp/menu-bar.el @@ -230,7 +230,7 @@ (bindings--define-key menu [project-open-file] '(menu-item "Open File In Project..." project-find-file :enable (menu-bar-non-minibuffer-window-p) - :help "Read an existing file in the current project into an Emacs buffer")) + :help "Read existing file that belongs to current project into an Emacs buffer")) (bindings--define-key menu [open-file] '(menu-item "Open File..." menu-find-file-existing :enable (menu-bar-non-minibuffer-window-p) @@ -357,7 +357,7 @@ :help "Search for a regexp in all tagged files")) (bindings--define-key menu [project-search] '(menu-item "Search in Project Files..." project-find-regexp - :help "Search for a regexp in files of the current project")) + :help "Search for a regexp in files belonging to current project")) (bindings--define-key menu [separator-tag-search] menu-bar-separator) (bindings--define-key menu [repeat-search-back] @@ -411,7 +411,7 @@ :help "Interactively replace a regexp in all tagged files")) (bindings--define-key menu [project-replace] '(menu-item "Replace in Project Files..." project-query-replace-regexp - :help "Interactively replace a regexp in files of the current project")) + :help "Interactively replace a regexp in files belonging to current project")) (bindings--define-key menu [separator-replace-tags] menu-bar-separator) @@ -1785,14 +1785,14 @@ mail status in mode line")) (defvar menu-bar-project-menu (let ((menu (make-sparse-keymap "Project"))) - (bindings--define-key menu [project-execute-extended-command] '(menu-item "Execute Extended Command..." project-execute-extended-command :help "Execute an extended command in project root")) - (bindings--define-key menu [project-query-replace-regexp] '(menu-item "Query Replace Regexp..." project-query-replace-regexp :help "Interactively replace a regexp in files of the current project")) - (bindings--define-key menu [project-or-external-find-regexp] '(menu-item "Find Regexp Including External Roots..." project-or-external-find-regexp :help "Search for a regexp in files of the current project or external files")) - (bindings--define-key menu [project-find-regexp] '(menu-item "Find Regexp..." project-find-regexp :help "Search for a regexp in files of the current project")) + (bindings--define-key menu [project-execute-extended-command] '(menu-item "Execute Extended Command..." project-execute-extended-command :help "Execute an extended command in project root directory")) + (bindings--define-key menu [project-query-replace-regexp] '(menu-item "Query Replace Regexp..." project-query-replace-regexp :help "Interactively replace a regexp in files belonging to current project")) + (bindings--define-key menu [project-or-external-find-regexp] '(menu-item "Find Regexp Including External Roots..." project-or-external-find-regexp :help "Search for a regexp in files belonging to current project or external files")) + (bindings--define-key menu [project-find-regexp] '(menu-item "Find Regexp..." project-find-regexp :help "Search for a regexp in files belonging to current project")) (bindings--define-key menu [separator-project-search] menu-bar-separator) (bindings--define-key menu [project-kill-buffers] '(menu-item "Kill Buffers..." project-kill-buffers :help "Kill the buffers belonging to the current project")) - (bindings--define-key menu [project-list-buffers] '(menu-item "List Buffers..." project-list-buffers :help "Pop up a window listing all Emacs buffers in the current project")) - (bindings--define-key menu [project-switch-to-buffer] '(menu-item "Switch To Buffer..." project-switch-to-buffer :help "Prompt for a buffer in the current project, and switch to it")) + (bindings--define-key menu [project-list-buffers] '(menu-item "List Buffers..." project-list-buffers :help "Pop up a window listing all Emacs buffers belonging to current project")) + (bindings--define-key menu [project-switch-to-buffer] '(menu-item "Switch To Buffer..." project-switch-to-buffer :help "Prompt for a buffer belonging to current project, and switch to it")) (bindings--define-key menu [separator-project-buffers] menu-bar-separator) (bindings--define-key menu [project-async-shell-command] '(menu-item "Async Shell Command..." project-async-shell-command :help "Invoke a shell command in project root asynchronously in background")) (bindings--define-key menu [project-shell-command] '(menu-item "Shell Command..." project-shell-command :help "Invoke a shell command in project root and catch its output")) @@ -1803,9 +1803,9 @@ mail status in mode line")) (bindings--define-key menu [project-switch-project] '(menu-item "Switch Project..." project-switch-project :help "Switch to another project and then run a command")) (bindings--define-key menu [project-vc-dir] '(menu-item "VC Dir..." project-vc-dir :help "Show the VC status of the project repository")) (bindings--define-key menu [project-dired] '(menu-item "Open Project Root" project-dired :help "Read the root directory of the current project, to operate on its files")) - (bindings--define-key menu [project-find-dir] '(menu-item "Open Directory..." project-find-dir :help "Open an existing directory in the current project")) - (bindings--define-key menu [project-or-external-find-file] '(menu-item "Open File Including External Roots..." project-or-external-find-file :help "Open an existing file in the current project or its external roots")) - (bindings--define-key menu [project-open-file] '(menu-item "Open File..." project-find-file :help "Open an existing file in the current project")) + (bindings--define-key menu [project-find-dir] '(menu-item "Open Directory..." project-find-dir :help "Open existing directory that belongs to current project")) + (bindings--define-key menu [project-or-external-find-file] '(menu-item "Open File Including External Roots..." project-or-external-find-file :help "Open existing file that belongs to current project or its external roots")) + (bindings--define-key menu [project-open-file] '(menu-item "Open File..." project-find-file :help "Open an existing file that belongs to current project")) menu)) (defun menu-bar-read-mail () @@ -2402,12 +2402,12 @@ Buffers menu is regenerated." 'menu-item "Select Buffer In Project..." 'project-switch-to-buffer - :help "Prompt for a buffer in the current project, and switch to it") + :help "Prompt for a buffer belonging to current project, and switch to it") (list 'list-buffers-in-project 'menu-item "List Buffers In Project..." 'project-list-buffers - :help "Pop up a window listing all Emacs buffers in the current project")) + :help "Pop up a window listing all Emacs buffers belonging to current project")) "Entries to be included at the end of the \"Buffers\" menu.") (defvar menu-bar-select-buffer-function 'switch-to-buffer From edd36786e1eb9d3c17d4a36bd13fc9f6b2090c85 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sat, 1 Jul 2023 12:46:37 +0300 Subject: [PATCH 9/9] ; * lisp/bookmark.el (bookmark-bmenu-locate): Doc fix (bug#64370). --- lisp/bookmark.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/bookmark.el b/lisp/bookmark.el index 11368910876..026257ff758 100644 --- a/lisp/bookmark.el +++ b/lisp/bookmark.el @@ -2419,7 +2419,7 @@ confirmation first." (defun bookmark-bmenu-locate () - "Display location of this bookmark. Displays in the minibuffer." + "Display the location of the bookmark for this line." (interactive nil bookmark-bmenu-mode) (let ((bmrk (bookmark-bmenu-bookmark))) (message "%s" (bookmark-location bmrk))))