15. Overview of the Ring Package
In this lesson, we will explore the fundamentals of the built-in ring package, which is useful for managing histories. We will leverage this package to implement a the prompt history feature of chatgpt.el package.
With the ring package, we can efficiently add or remove elements and, given any element, easily access its previous or next neighbor.
Creating Rings and Inserting Elements¶
In this section, we demonstrate two methods to create rings and two methods for inserting elements.
First, we create a ring variable r with a size of 3 using the make-ring function:
We confirm that the ring is empty by checking:
Next, we insert three elements into the ring using the ring-insert function:
(ring-insert r "foo-1") ;; "foo-1"
(ring-insert r "foo-2") ;; "foo-2"
(ring-insert r "foo-3") ;; "foo-3"
To view the elements in the ring, we can use the ring-elements function. For our ring r, it returns the following list, "foo-1" being the oldest element and "foo-3" the newest:
Next, we insert a fourth element, "foo-4", into this full ring:
Listing the elements again, we can observe that the oldest element "foo-1" has been removed, the ring rotated, and "foo-4" is now the newest element:
Now, let's explore another approach for creating rings and inserting elements that allows for ring enlargement without dropping the oldest element.
We initialize the ring r with three elements using ring-convert-sequence-to-ring, which converts a sequence into a ring:
We can list r elements:
Now, we use ring-insert+extend to insert "foo-4" while enlarging the ring instead of discarding the oldest element:
The updated elements in ring r now show that the oldest element remains the same, and the ring has been enlarged:
Accessing Ring Elements¶
In this section, we learn how to access elements in a ring.
First, we define the ring r again with three elements:
We can confirm the elements in ring r as follows:
Now, we use the ring-ref function to access elements by their index:
To retrieve the next or previous element for a given value, we use the ring-next and ring-previous functions:
If we attempt to get the next element of the oldest entry, ring-next wraps back to the newest element:
Conversely, attempting to get the previous element of the newest entry wraps back to the oldest:
Lastly, note that trying to access the next or previous element of a non-existent item raises an error:
In the subsequent lesson, we will apply the concepts from this lesson and the previous one to implement the prompt history feature.