Skip to content

Walheimat/partial-recall

Repository files navigation

partial-recall

Coverage Status

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.

Installation

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

Concepts

Memories and moments

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 buffer, 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:

  1. A new moment is created from that buffer by “remembering” it; this means storing it in the current tab’s memory.
  2. An existing moment is “recollected”, which in turn means one of two things:
    1. If it belongs to another memory, it may be “reclaimed” depending on partial-recall-intermediate-term.
    2. If it belongs to the current memory, it is “reinforced”, that is, pushed to the top of the ring again.

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.

Permanence

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:

  1. The user calls partial-recall-make-permanent and selects its buffer.
  2. The moment has been revisited and re-inserted so often that its focus reached partial-recall-plasticity-implant-threshold.
  3. 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.

Concentration

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.

Meaningful buffers and buffer traits

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:

  1. buffer-file-name, meaning any buffer that has a file name is meaningful.
  2. partial-recall--not-filtered-p which means the buffers name is not matched by partial-recall-filter.
  3. partial-recall--not-in-view-mode and partial-recall--not-to-be-viewed-p that prevent buffers in view-mode to be considered.
  4. partial-recall--not-banished-p which means the buffer was not the target of partial-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.

Configuration

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 and plasticity).

(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 nil) ;; Whether to log actions. Set to 1 for info logs and 0 for debug logs.
  (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 . 1) (reinsert . 2) (concentrate . 2))) ;; Focus gained from actions.

  (partial-recall-concentration-cycle 60) ;; Amount of seconds between checking whether a buffer remained visible.

  (partial-recall-plasticity-implant-threshold 20) ;; Amount of focus needed before auto-implanting.

  :config
  (partial-recall-mode)
  (partial-recall-concentration-mode)
  (partial-recall-plasticity-of-memory-mode)
  (partial-recall-plasticity-of-moment-mode)

  ;; If you use `consult', you can add the provided buffer source.
  (with-eval-after-load 'consult
    (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

Using the menu

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.

Hooks

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).

About

Short-term buffer memory

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages