Subject: Re: bug#68921: File and Buffer register functions.

From: Thierry Volpiatto <[email-masked]>
Date: Sun, 04 Feb 2024 06:30:12 +0000

Barra Ó Catháin via "Bug reports for GNU Emacs, the Swiss army knife of
text editors" <[email-masked]> writes:

> Hello!
>
> I noticed that files and buffers don't have "to-register" functions of
> their own, rather, relying on (set-register).

The reason is that when your use `point-to-register`, a position is
recorded in the buffer, and when you kill this buffer your register
record (a marker) is transformed in a file-query register:

Example:

If I do C-x r SPC in init.el, register record a register like this:

    (119 . #<marker at 76829 in init.el>)

Then I kill init.el buffer, I have now in register-alist instead of the
register above:

    (122 file-query "/path/to/init.el" 76829) 

This register is writable i.e. you can save it for further emacs
sessions.

So there is no really needs for function that register files or buffers.

That said if you really want to add such functions, you will have to add
for each function the corresponding defmethod, here an example with a
delete register function, you will find other examples in register.el:

    (defun register-delete (register)
        (interactive (list (register-read-with-preview "Delete register: ")))
        (setq register-alist (delete (assoc register register-alist)
                                     register-alist)))

    (cl-defmethod register-preview-command-info ((_command (eql register-delete)))
            (make-register-preview-info
             :types '(all)
             :msg "Delete register `%s'"
             :act 'modify
             :smatch t))

> To that end, I have written 4 functions that I feel may be useful and
> "complete the set" of register functions.
>
> From d697dc8b3fb66fb3c37851ab1d33af665870ae1d Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Barra=20=C3=93=20Cath=C3=A1in?= <[email-masked]>
> Date: Fri, 2 Feb 2024 21:45:05 +0000
> Subject: [PATCH 1/4] Added buffer and file to register functions.
>
> Added buffer-to-register, file-to-register, current-buffer-to-register,
> and current-file-to-register to register.el.

> ---
>  lisp/register.el | 44 ++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 44 insertions(+)
>
> diff --git a/lisp/register.el b/lisp/register.el
> index 822467a0d72..8fff867e547 100644
> --- a/lisp/register.el
> +++ b/lisp/register.el
> @@ -685,6 +685,50 @@ Interactively, prompt for REGISTER using `register-read-with-preview'."
>    (let ((val (get-register register)))
>      (register-val-jump-to val delete)))
>  
> +(defun file-to-register (register file-name)
> +  "Inserts a given file into a register.  To visit the file, use
> +  \\[jump-to-register].
> +
> +Called from Lisp, takes two args: REGISTER, and FILE-NAME.
> +
> +Interactively, prompt for REGISTER using `register-read-with-preview',
> +and prompt for FILE-NAME using `read-file-name'."
> +  (interactive (list (register-read-with-preview "File to register: ")
> +                     (read-file-name "File: ")))
> +  (set-register register `(file . ,file-name)))
> +
> +(defun current-file-to-register (register)
> +  "Places the current file name into a register.  To visit the file, use
> +\\[jump-to-register].
> +
> +Called from Lisp, takes one arg: REGISTER.
> +
> +Interactively, prompt for REGISTER using `register-read-with-preview."
> +  (interactive (list (register-read-with-preview "Current file to register: ")))                
> +  (set-register register `(file . ,(buffer-file-name))))
> +
> +(defun buffer-to-register (register buffer)
> +  "Inserts a given buffer into a register.  To visit the buffer, use
> +\\[jump-to-register].
> +
> +Called from Lisp, takes two args: REGISTER, and BUFFER.
> +
> +Interactively, prompt for REGISTER using `register-read-with-preview', and
> +prompt for BUFFER-NAME using `read-buffer'."
> +  (interactive (list (register-read-with-preview "Buffer to register: ")
> +                     (read-buffer "Buffer: ")))
> +  (set-register register `(buffer . ,buffer)))
> +
> +(defun current-buffer-to-register (register)
> +  "Places the current buffer into a register.  To visit the buffer, use
> +\\[jump-to-register].
> +
> +Called from Lisp, takes one arg: REGISTER.
> +
> +Interactively, prompt for REGISTER using `register-read-with-preview.'"
> +  (interactive (list (register-read-with-preview "Current buffer to register: ")))                
> +  (set-register register `(buffer . ,(current-buffer))))
> +
>  (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'.
> -- 
> 2.43.0
>
> From f53b313bbf9e033ca0aea9e1e1e4a547d6b5b194 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Barra=20=C3=93=20Cath=C3=A1in?= <[email-masked]>
> Date: Fri, 2 Feb 2024 22:28:44 +0000
> Subject: [PATCH 2/4] Added bindings for the new "to register" functions
>
> Added bindings for "current-file-to-register" and
> "current-buffer-to-register" to bindings.el.
> ---
>  lisp/bindings.el | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/lisp/bindings.el b/lisp/bindings.el
> index 4690897fed4..21767f37f61 100644
> --- a/lisp/bindings.el
> +++ b/lisp/bindings.el
> @@ -1570,7 +1570,10 @@ if `inhibit-field-text-motion' is non-nil."
>    "n"     #'number-to-register
>    "+"     #'increment-register
>    "w"     #'window-configuration-to-register
> -  "f"     #'frameset-to-register)
> +  "f"     #'frameset-to-register
> +  "F"     #'current-file-to-register
> +  "B"     #'current-buffer-to-register)
> +
>  (define-key ctl-x-map "r" ctl-x-r-map)
>  
>  (define-key esc-map "q" 'fill-paragraph)
> -- 
> 2.43.0
>
> From 23dcde96046a9edc04bca68579174300dde5cd44 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Barra=20=C3=93=20Cath=C3=A1in?= <[email-masked]>
> Date: Sat, 3 Feb 2024 20:34:45 +0000
> Subject: [PATCH 3/4] Basic error checking for new register functions
>
> ---
>  lisp/register.el | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/lisp/register.el b/lisp/register.el
> index 8fff867e547..cfb3c6a2b13 100644
> --- a/lisp/register.el
> +++ b/lisp/register.el
> @@ -695,7 +695,9 @@ Interactively, prompt for REGISTER using `register-read-with-preview',
>  and prompt for FILE-NAME using `read-file-name'."
>    (interactive (list (register-read-with-preview "File to register: ")
>                       (read-file-name "File: ")))
> -  (set-register register `(file . ,file-name)))
> +  (if (file-exists-p file-name)
> +      (set-register register `(file . ,file-name)))
> +  (user-error "File does not exist.")
>  
>  (defun current-file-to-register (register)
>    "Places the current file name into a register.  To visit the file, use
> @@ -717,7 +719,9 @@ Interactively, prompt for REGISTER using `register-read-with-preview', and
>  prompt for BUFFER-NAME using `read-buffer'."
>    (interactive (list (register-read-with-preview "Buffer to register: ")
>                       (read-buffer "Buffer: ")))
> -  (set-register register `(buffer . ,buffer)))
> +  (if (buffer-p buffer)
> +      (set-register register `(buffer . ,buffer))
> +    (user-error "Not a buffer."))
>  
>  (defun current-buffer-to-register (register)
>    "Places the current buffer into a register.  To visit the buffer, use
> -- 
> 2.43.0
>
> From cf28598990cb374f6e3bedb0b5c49e0ccc861477 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Barra=20=C3=93=20Cath=C3=A1in?= <[email-masked]>
> Date: Sat, 3 Feb 2024 20:43:05 +0000
> Subject: [PATCH 4/4] Documentation in Info for new register commands
>
> Simple modification to regs.texi to refer to the new register commands.
> ---
>  doc/emacs/regs.texi | 15 +++++++++------
>  1 file changed, 9 insertions(+), 6 deletions(-)
>
> diff --git a/doc/emacs/regs.texi b/doc/emacs/regs.texi
> index cac5b32c566..e9fb2c74773 100644
> --- a/doc/emacs/regs.texi
> +++ b/doc/emacs/regs.texi
> @@ -291,11 +291,13 @@ numeric argument stores zero in the register.
>  @cindex saving buffer name in a register
>  
>    If you visit certain file names frequently, you can visit them more
> -conveniently if you put their names in registers.  Here's the Lisp code
> -used to put a file @var{name} into register @var{r}:
> +conveniently if you put their names in registers.  You may use @kbd{C-x
> +r F} to place the currently visited file in a register. 
> +
> +Here's the Lisp code used to put a file @var{name} into register @var{r}:
>  
>  @smallexample
> -(set-register @var{r} '(file . @var{name}))
> +(file-to-register @var{r} @var{name})
>  @end smallexample
>  
>  @need 3000
> @@ -303,7 +305,7 @@ used to put a file @var{name} into register @var{r}:
>  For example,
>  
>  @smallexample
> -(set-register ?z '(file . "/gd/gnu/emacs/19.0/src/ChangeLog"))
> +(file-to-register ?z "/gd/gnu/emacs/19.0/src/ChangeLog")
>  @end smallexample
>  
>  @noindent
> @@ -314,12 +316,13 @@ puts the file name shown in register @samp{z}.
>  restore a frame configuration.)
>  
>    Similarly, if there are certain buffers you visit frequently, you
> -can put their names in registers.  For instance, if you visit the
> +can put their names in registers.  You may use @kbd{C-x r B} to store
> +the current buffer in a register.  Or, 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:
>  
>  @smallexample
> -(set-register ?m '(buffer . "*Messages*"))
> +(buffer-to-register ?m "*Messages*")
>  @end smallexample
>  
>    To switch to the buffer whose name is in register @var{r}, type

-- 
Thierry