partial-recall
provides a narrow buffer scope built on top of
tab-bar-mode
. It turns each tab into a living (that is: forgetful)
workspace. Each meaningful buffer that is first visited in a tab will
be associated with that tab until a limit is met whereupon the oldest
buffer is forgotten. If a newly visited buffer is already associated
with another tab, it may be reclaimed (automatically or manually).
See Concepts section below for more information.
If you use straight
or quelpa
, you know what to do.
If you’re on Emacs >29, I recommend using package-vc-install
.
Alternatively, provided you have Cask, you can install the package
with make package-install
after initializing the submodule dinghy
.
git clone --recurse-submodules https://github.com/Walheimat/partial-recall.git cd partial-recall/ make package install
The association buffer → tab is done using two structures: memories and moments.
A memory is a ring of moments and a key used for look-up. The size of
the ring is determined by partial-recall-memory-size
.
A moment is a buf 8000 fer, a timestamp at which it was focused, a count of how many times it was focused and a flag indicating whether it is permanent (see below on topics Permanence and Concentration).
Visiting a buffer will schedule its handling which is to say that
handling is delayed by partial-recall-handle-delay
seconds. So if
you were to quickly switch between buffers, only the one you linger on
eventually would be handled (handling is a no-op if the buffer is no
longer visible at that point).
Handling a buffer will do one of two things:
- A new moment is created from that buffer by “remembering” it; this means storing it in the current tab’s memory.
- An existing moment is “recollected”, which in turn means one of two
things:
- If it belongs to another memory, it may be “reclaimed” depending
on
partial-recall-intermediate-term
. - If it belongs to the current memory, it is “reinforced”, that is, pushed to the top of the ring again.
- If it belongs to another memory, it may be “reclaimed” depending
on
Since memories are rings, moments will leave the ring after more
moments than its size will allow have been added without revisiting
them. This removal is called “forgetting”. You may also call
partial-recall-forget
(or partial-recall-forget-some
) manually (or
kill the buffer). You may also call partial-recall-banish
to not
just forget a buffer but no longer add it to any memory in whose
context it is switched to.
If you enable partial-recall-plasticity-of-memory-mode
memories will
grow instead of forgetting the oldest moment if it itself is still not
that old or the youngest moment is very young. This (like reclaiming)
is determined by partial-recall-intermediate-term
.
Forgotten buffers are not lost, they are marked as belonging to the
“subconscious” from which they can be “lifted” using
partial-recall-lift
(or partial-recall-retrieve
).
You may also push buffers from the current memory to another using
partial-recall-reject
.
Buffers that were removed from a memory can also be retrieved using
partial-recall-retrieve
provided that they were either reclaimed by
other memories or still reside in the subconscious.
Moments normally age out of its memory unless their buffers are
re-visited (or focused upon) and refreshed before that would happen.
If you enable partial-recall-plasticity-of-moment-mode
“Permanent”
moments don’t suffer this fate. There are three scenarios by which a
moment is made permanent:
- The user calls
partial-recall-make-permanent
and selects its buffer. - The moment has been revisited and re-inserted so often that its
focus reached
partial-recall-plasticity-implant-threshold
. - Mode
partial-recall-concentration-mode
is on and the moment has been concentrated upon to reach that same threshold.
Different actions affect moments differently. Concentration, explained
below, allots the biggest amount of focus. The values are governed by
partial-recall-intensities
.
The reverse of implanting is “excising” which
partial-recall-make-permanent
will do if called with C-u
.
Permanent buffers can still be forgotten manually.
Actions like swapping a moment from one memory to another even reduce
focus. In partial-recal-plasticity-of-moment-mode
such moments may
also lose previously gained permanence.
Every partial-recall-concentration-cycle
seconds partial-recall
will “concentrate” on the current-buffer
. If the focused buffer
doesn’t change (or at least remains visible) between cycles its focus
will increase (see Permanence) otherwise concentration is broken and
will begin again for the current buffer.
Note that concentration is a no-op if the current-buffer
is not a
meaningful buffer. In this instance, concentration is deferred. During
this phase attempts to re-focus are made more rapidly (using a tenth
of partial-recall-concentration-cycle
). If the previously focused
buffer can be focused again after the first repeat, concentration can
be resumed.
Focus has no upper limit, meaning it may easily transcend
partial-recall-plasticity-implant-threshold
. As of now this has no
further consequences.
Switching tabs has concentration shift to the new tab’s current buffer and resets the cycle.
To enable this behavior, enable partial-recall-concentration-mode
.
partial-recall
only “remembers” buffers that are “meaningful”. This
is governed by a list of predicates listed in
partial-recall-meaningful-traits
. They all must return t
to mark a
meaningful buffer. If you set it to '(always)
all buffers would be
considered meaningful.
By default only three traits are in the list:
buffer-file-name
, meaning any buffer that has a file name is meaningful.partial-recall--not-filtered-p
which means the buffers name is not matched bypartial-recall-filter
.partial-recall--not-in-view-mode
andpartial-recall--not-to-be-viewed-p
that prevent buffers inview-mode
to be considered.partial-recall--not-banished-p
which means the buffer was not the target ofpartial-recall-banish
.
For these three traits property
partial-recall-non-meaningful-explainer
is set which is read by
partial-recall-explain-omission
if you want to know why a particular
buffer was omitted (also present in the help echo of the mode-line
lighter). So if you add your own trait here, consider doing the
following:
(put 'my/partial-recall-trait 'partial-recall-non-meaningful-explainer "I have my reasons")
There are also partial-recall-memorable-traits
. These are functions
called when the user invokes partial-recall-flush
to clear up the
current memory. The default function checks whether a moment is
relatively young. If you have
partial-recall-plasticity-of-moment-mode
on, moments that have
permanence or are half-way towards automatically gaining it are also
spared. If you have partial-recall-hygiene-mode
on flushing happens
automatically after a delay configured by
partial-recall-hygiene-idle-delay
.
partial-recall
will turn on tab-bar-mode
if it isn’t already turned
on. partial-recall-mode
will make sure all newly created frames are
taken into account.
You likely want to enable all optional modes (concentration, plasticity and hygiene).
(use-package partial-recall
:custom
(partial-recall-memory-size 10) ;; Size of a regular memory.
(partial-recall-handle-delay 3) ;; The delay before a buffer is handled (remembered or re-inforced).
(partial-recall-buffer-limit 10) ;; The number of buffers in the ring.
(partial-recall-intermediate-term 1200) ;; The age (in seconds) that, when exceeded, will allow reclaiming.
(partial-recall-repress t) ;; Whether forgotten buffers should (eventually) be killed.
(partial-recall-auto-switch t) ;; Whether to switch to a moment's tab automatically.
(partial-recall-lighter-prefix "pr") ;; What you will in the mode-line.
(partial-recall-record-triggers '(consult-buffer)) ;; Commands that might obscure buffers before they are handled.
(partial-recall-log t) ;; Whether to log actions. Set to t or 1 for info logs and 0 for debug logs.
(partial-recall-log-echo nil) ;; Whether to also log to echo area.
(partial-recall-log-prefix "PR") ;; Message prefix for log messages.
(partial-recall-filter '("COMMIT_EDITMSG")) ;; Regexes of names that should be ignored.
(partial-recall-meaningful-traits '(buffer-file-name ;; List of functions that determine eligible buffers.
partial-recall--not-filtered-p
partial-recall--not-in-view-mode-p
partial-recall--not-to-be-viewed-p
partial-recall--not-banished-p))
(partial-recall-memorable-traits '(partial-recall--gracedp)) ;; Don't flush recent moments.
(partial-recall-intensities '((swap . -10) (reinsert . 20) (concentrate . 4))) ;; Focus gained (or lost) from actions.
(partial-recall-concentration-cycle 10) ;; Amount of seconds between checking whether a buffer remained visible.
(partial-recall-plasticity-implant-threshold 100) ;; Amount of focus needed before auto-implanting.
(partial-recall-hygiene-idle-delay 5) ;; Idle time (in seconds) when hygiene routine should run.
(partial-recall-hygiene-flush t) ;; Whether to flush memories regularly.
(partial-recall-hygiene-warn-on-full t) ;; Whether to warn about full memories (once).
(partial-recall-x-consult-narrow-key ?u) ;; The key used to narrow using `consult-buffer'.
(partial-recall-menu-display-command 'pop-to-buffer) ;; Command used to display the menu buffer.
:config
(partial-recall-mode)
(partial-recall-concentration-mode)
(partial-recall-plasticity-of-memory-mode)
(partial-recall-plasticity-of-moment-mode)
(partial-recall-hygiene-mode)
;; If you use `consult', you can add the provided buffer source.
(with-eval-after-load 'consult
(require 'partial-recall-x)
(add-to-list
'consult-buffer-sources
'partial-recall-x-consult-buffer-source))
:bind-keymap
(("C-c b" . partial-recall-command-map)))
I suggest to just bind the command map as shown above, otherwise you probably want to bind the following commands:
partial-recall-forget
partial-recall-banish
partial-recall-make-permanent
partial-recall-lift
partial-recall-menu
partial-recall-reclaim
partial-recall-remember
partial-recall-switch-to-buffer
partial-recall-switch-to-buffer-other-window
partial-recall-meld
partial-recall-flush
partial-recall-next
partial-recall-previous
partial-recall-forget-some
partial-recall-explain-omission
partial-recall-reject
partial-recall-retrieve
partial-recall-pop-to-logs
You can act on multiple moments simultaneously using
partial-recall-menu
. It will pop open a buffer menu where you can
reclaim (for the current memory), reinforce, forget and implant (or
excise) using r
, f
, i
(or C-u i
), followed by x
to execute
all commands. You can unmark with u
, display a moment with e
or
RET
.
This can be useful if you want to work on a smaller subset of the current moments in a new memory.
If you want to include subconscious buffers, call
partial-recall-menu
with C-u
or type s
in the buffer.
You currently can hook into the following three actions:
- After a memory was probed (which passes the memory)
- After a moment’s permanence has changed (which passes moment and permanence)
- After a moment was inserted (passing the inserted moment).