#+title: Change log of Beframe
#+author: Protesilaos Stavrou
#+email: info@protesilaos.com
#+options: ':nil toc:nil num:nil author:nil email:nil

This document contains the release notes for each tagged commit on the
project's main git repository: <https://git.sr.ht/~protesilaos/beframe>.

The newest release is at the top.  For further details, please consult
the manual: <https://protesilaos.com/emacs/beframe>.

* 1.0.0 on 2023-11-17
:PROPERTIES:
:CUSTOM_ID: h:9a00ab34-a07f-4bb3-9397-6b1383fcebca
:END:

~beframe~ is in a stable state. This release formalises a set of
stability enhancements and quality-of-life improvements.

** The menu bar helps you discover Beframe commands
:PROPERTIES:
:CUSTOM_ID: h:e1aec53d-ed00-4eed-8763-78f7ad9c307d
:END:

A submenu with Beframe commands is available to users of
~menu-bar-mode~. It is available at =Buffers > BEFRAME buffers=. Check
the original announcement, which includes screenshots:
<https://protesilaos.com/codelog/2023-10-08-emacs-beframe-menu/>.

[ As an aside, never tell a new user to add ~(menu-bar-mode -1)~ to
  their Emacs init file. It is not helpful. ]

** The sample integration with ~consult~ can flip between recent buffers
:PROPERTIES:
:CUSTOM_ID: h:377b869e-a552-41e7-8e52-343a434a77af
:END:

In the manual of ~beframe~ there is a section about augmenting the
~consult-buffer~ command with a new source of beframed buffers
(buffers specific to the current frame). Edgar Vincent made a change
that sorts buffers by last viewed, meaning that the previous buffer is
at the top of the list. The change is within the ~15 line limit and
thus Edgar does not need to assign copyright to the Free Software
Foundation. Discussed on the mailing list:
<https://lists.sr.ht/~protesilaos/general-issues/%3C878r97fxmc.fsf%40protesilaos.com%3E>.

Refer to the manual for the code to integrate ~beframe~ with ~consult~:
<https://protesilaos.com/emacs/beframe#h:1c2d3d64-aa7b-4585-a418-ccedbb548b38>.

NOTE that you do not need ~consult~ to use ~beframe~: (i) the
~beframe-mode~ makes the regular ~switch-to-buffer~ work in a beframed
way and/or (ii) use the ~beframe-buffer-menu~ to get a list of the
beframed buffers (call the latter command with a prefix key (=C-u= by
default) to select a frame whose buffers you want to list).

** The ~beframe-rename-function~ can take a ~nil~ value
:PROPERTIES:
:CUSTOM_ID: h:d64e0861-15a7-40ad-8ece-aba232840fb8
:END:

This was always the intent, though the code did not honour it. Thanks
to Karthik Chikmagalur for reporting the bug on the mailing list:
<https://lists.sr.ht/~protesilaos/general-issues/%3C87a5w8yi1n.fsf%40gmail.com%3E>.

** General refinements
:PROPERTIES:
:CUSTOM_ID: h:494d4a62-567e-4886-af96-fa9e93e48083
:END:

- Commands that prompt for a frame (e.g. ~beframe-assume-frame-buffers~)
  no longer try to perform their work if a single Emacs frame is
  available. Instead, they return a ~user-error~.

- The buffer that was current when a new frame was created is no
  longer part of the new frame's buffer list. This means that the new
  frame starts clean, including only the buffer specified in the user
  option ~beframe-global-buffers~.

- The code that renames a new frame based is better at inferring the
  correct name. It now finds the =project.el= name, if available. The
  manual explains how to use Beframe with projects:
  <https://protesilaos.com/emacs/beframe#h:5b751614-8749-4aa8-aaed-f181beaddc57>
  (to me, this is a killer feature).

- Simplified how frames are set up. This guarantees that our functions
  are called in the desired order.

* 0.3.0 on 2023-05-21
:PROPERTIES:
:CUSTOM_ID: h:59120517-f6e0-4bb8-a495-c5eb40654d6a
:END:

** Use more descriptive names for assume/unassume commands
:PROPERTIES:
:CUSTOM_ID: h:a3b24770-40a2-4c97-8403-62bbf79720fa
:END:

Beframe limits the buffer list to buffers that are visited in the
current frame.  I provide commands to assume (add) or unassume
(remove) buffers from other frames, making for a powerful and flexible
workflow:

- In bulk :: Assume/unassume the (i) entire buffer list of a frame, or
  the (ii) consolidated buffer list of all frames.

- Selectively :: Use minibuffer completion to compile a list of
  buffers to assume/unassume (iii) from the given frame, or (iv)
  buffers from the consolidated buffer list.

The commands that operate selectively are renamed to better describe
what they do.  We thus have:

| Deprecated name                   | New name                                           |
|-----------------------------------+----------------------------------------------------|
| beframe-assume-buffers            | beframe-assume-frame-buffers-selectively           |
| beframe-assume-buffers-all-frames | beframe-assume-buffers-selectively-all-frames      |
| beframe-unassume-buffers          | beframe-unassume-current-frame-buffers-selectively |

To avoid potential confusion, the following command aliases are
discontinued:

- ~beframe-add-buffers~
- ~beframe-remove-buffers~
- ~beframe-add-frame-buffers~
- ~beframe-remove-frame-buffers~

** Provide the ~beframe-prefix-map~
:PROPERTIES:
:CUSTOM_ID: h:a34d0635-4022-41b0-bb41-3b6286c954cc
:END:

This is a keymap that binds the Beframe commands to recommended keys.
As with all Emacs key bindings, those are configurable.

I call it a "prefix" keymap because it is not bound anywhere and
cannot be used by default.  The user must explicitly bind it to a key,
which will be treated as a prefix key.  For example:

#+begin_src emacs-lisp
(define-key global-map (kbd "C-c b") beframe-prefix-map)
#+end_src

With the above code, =C-c b= becomes the prefix key that invokes
Beframe commands.  Type =C-c b C-h= to show the available key
bindings (by default =C-h= as a suffix to an incomplete key sequence
produces a Help buffer that links to all the available bindings).

The ~beframe-prefix-map~ and ~beframe-mode~ are used independent of
each other.

** Miscellaneous
:PROPERTIES:
:CUSTOM_ID: h:b5dcf56b-3668-4f3e-9743-771ce9b1eeb0
:END:

- Simplify how ~beframe-rename-function~ is added by the
  ~beframe-mode~.
- Refine the application of ~beframe-create-frame-scratch-buffer~ by
  the ~beframe-mode~.
- Tweak the ~beframe-buffer-sort-visibility~ function to be consistent
  with the style of =beframe.el=.
- Rewrite parts of the manual to reference the aforementioned.

* 0.2.0 on 2023-03-27
:PROPERTIES:
:CUSTOM_ID: h:ba53a28d-7e85-4c9b-9770-22abb9263473
:END:

There were no release notes for the initial version of Beframe.  Watch
the video demo I produced on 2023-02-28 to get an overview of what
this package is all about:
<https://protesilaos.com/codelog/2023-02-28-emacs-beframe-demo/>.

In short: beframe your buffers, not your outlook.  Oops that is for
the philosophy blog! 🙃

** A beframed buffer menu
:PROPERTIES:
:CUSTOM_ID: h:345543c7-f61c-4656-964e-53f338ec7850
:END:

The command ~beframe-buffer-menu~ produces a dedicated buffer with a
list of buffers for the current frame.  This is the counterpart of
~beframe-switch-buffer~.  When called with a prefix argument (=C-u=
with default key bindings), it prompts for a frame whose buffers it
will display.

** Frame-specific scratch buffer
:PROPERTIES:
:CUSTOM_ID: h:69df2c63-c509-4063-bf24-b6aa39c6cfca
:END:

The user option ~beframe-create-frame-scratch-buffer~ allows
~beframe-mode~ to create a frame-specific scratch buffer that runs the
~initial-major-mode~.  This is done upon the creation of a new frame
and the scratch buffer is named after the frame it belongs to.  For
example, if the frame is called =modus-themes=, the corresponding
scratch buffer is =*scratch for modus-themes*=.  Set this user option
to ~nil~ to disable the creation of such scratch buffers.

The user option ~beframe-kill-frame-scratch-buffer~ is the counterpart
of ~beframe-create-frame-scratch-buffer~.  It kills the frame-specific
scratch buffer after the frame is deleted.  Set this user option to
~nil~ to disable the killing of such buffers.

** Assuming and unassuming buffers
:PROPERTIES:
:CUSTOM_ID: h:b0546404-2e70-44e4-84c9-e7fbf0786d04
:END:

Beframe makes it possible to add or remove buffers from the list of
buffers associated with the current frame.  This provides for a
flexible workflow where buffers can be initially beframed yet
consolidated into new lists on demand.

*** Assuming buffers
:PROPERTIES:
:CUSTOM_ID: h:4ec70ff0-531c-4a9c-9509-0ee49d26da71
:END:

To assume buffers is to include them in the buffer list associated
with the current frame.

- The command ~beframe-assume-frame-buffers~ (alias
  ~beframe-add-frame-buffers~) prompts for a frame and then copies its
  buffer list into the current frame.

- The command ~beframe-assume-buffers~ (alias ~beframe-add-buffers~)
  adds buffers from a given frame to the current frame.  In
  interactive use, the command first prompts for a frame and then asks
  about the list of buffers therein.  The to-be-assumed buffer list is
  compiled with ~completing-read-multiple~.  This means that the user
  can select multiple buffers, each separated by the ~crm-separator~
  (typically a comma).

- The command ~beframe-assume-buffers-all-frames~ prompts with
  minibuffer completion for a list of buffers to assume.  The
  interface is the same as that of ~beframe-assume-buffers~ except
  that there is no prompt for a frame: buffers belong to the
  consolidated buffer list (all frames).

- The command ~beframe-assume-all-buffers-no-prompts~ unconditionally
  assumes the consolidated buffer list.

*** Unassuming buffers
:PROPERTIES:
:CUSTOM_ID: h:b98f5c92-23d6-464a-9001-9531e513dd73
:END:

To unassume buffers is to omit them from the buffer list associated with
the current frame.

- The command ~beframe-unassume-frame-buffers~ (alias
  ~beframe-remove-frame-buffers~) prompts for a frame and then removes
  its buffer list from the current frame.

- The command ~beframe-unassume-buffers~ (alias
  ~beframe-remove-buffers~) removes buffers from the current frame.
  In interactive use, the to-be-unassumed buffer list is compiled with
  ~completing-read-multiple~.  This means that the user can select
  multiple buffers, each separated by the ~crm-separator~ (typically a
  comma).

- The command ~beframe-unassume-all-buffers-no-prompts~ unconditionally
  unassumes the consolidated buffer list, but preserves the list
  stored in the user option ~beframe-global-buffers~.

** Sort beframed buffers from Lisp
:PROPERTIES:
:CUSTOM_ID: h:a72b304d-4dc4-48c2-8d29-7ccac1984422
:END:

This is courtesy of Tony Zorman:
<https://lists.sr.ht/~protesilaos/general-issues/%3C87edq4n3qt.fsf%40hyperspace%3E>.

#+begin_quote
commit dfa4678c208e1e5c41413f2d39416f84c21f28ff
Author: Tony Zorman <soliditsallgood@mailbox.org>
Date:   Sat Mar 4 11:48:17 2023 +0100

  Add the ability to sort the buffer list

  Some completion libraries, like consult, give the user the option to
  sort the list of buffers according to some strategy.  For example,
  sorting by visibility—in the sense that one is first shown hidden
  buffers, then visible ones, and only then the current buffer—may be
  preferrable when deciding to switch buffers via consult-buffer.

  Since beframe.el can be used as a consult source (see the manual),
  endowing beframe--buffer-list with an arbitrary sort function greatly
  improves the synergy between the two libraries.

 beframe.el | 56 ++++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 42 insertions(+), 14 deletions(-)
#+end_quote

The manual explains how this works in practice:
<https://protesilaos.com/emacs/beframe#h:1c2d3d64-aa7b-4585-a418-ccedbb548b38>.
Thanks to Tony Zorman for including the reference to the sorting mechanism!
