Metadata-Version: 2.1
Name: recent_items_list
Version: 1.1.3
Summary: RecentItemsList acts like a list, except that calling the "bump()" method on it
Author-email: Leon Dionne <ldionne@dridesign.sh.cn>
Description-Content-Type: text/markdown
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.10
Classifier: Intended Audience :: Developers
Requires-Dist: pytest ; extra == "devel"
Project-URL: Home, https://github.com/Zen-Master-SoSo/recent_items_list
Provides-Extra: devel

# recent_items_list

Provides finite length Last Recently Used (LRU) caches.

## RecentItemsList

A class which stores any type of object.

Appending or "bump"-ing items adds them to the beginning of the list. If the
"maxlen" number of items already exist, the last item is dropped from the list.

By default, only the last 10 items are kept in the list. You can change this by
setting the "maxlen" property on an instance of RecentItemsList. Setting the
"maxlen" property to < 1 makes for an infinite length list, constrained only by
system resourecs.

The two most used methods are "bump" and "remove".

### bump

Bump the given item to the beginning of the list. If the given item is not in
the list, inserts it at the beginning.

```python
recent_items.bump(thing)
```

### remove

Removes the given item *if it is in the list*. Does nothing if the item is not
in the list.

```python
recent_items.remove(thing)
```

### on_change

Registers a callback which is run every time the list changes.
The callback must have the signature:

```python
def item_list_changed(self, items):
```

...where "item_list_changed" is an example function name.

### clear

Removes all items from the list


## RecentFilesList

This class extends RecentItemsList, providing a "prune" function to clear the
list only of files which don't exist.

### prune

Removes files which no longer exist.

## Example:

This is a simple implementation of a "Recent Files" menu in PyQt.

Instantiation:

```python
def __init__(self):
	self.recent_files = RecentFilesList(self.settings.value(
		"recent_files", defaultValue = []))
	self.menuOpen_Recent.aboutToShow.connect(self.fill_recent_file_menu)
```

Filling the Qt menu:

```python
@pyqtSlot()
def fill_recent_file_menu(self):
	self.menuOpen_Recent.clear()
	actions = []
	for filename in self.recent_files:
		action = QAction(filename, self)
		action.triggered.connect(partial(self.load_file, filename))
		actions.append(action)
	self.menuOpen_Recent.addActions(actions)
```

Opening a file:

```python
def open(self, filename):
	self.recent_files.bump(filename)
	[...]
```

Saving to a QSettings instance:

```python
self.settings.setValue("recent_files", self.recent_files.items)
```

An alternate method of saving the most recent file list without having to
explicitly save the changes, is to provide a callback which will be called
whenever the list changes, which saves the list to QSettings:

```python
self.recent_files = RecentFilesList(self.settings.value(
	"recent_files", defaultValue = []))
self.recent_files.on_change(self.save_recent_files)

def save_recent_files(self, items):
	self.settings.setValue("recent_files", items)
```

## Another complete example:

```python
from functools import partial
from recent_items_list import RecentFilesList

VENDOR_NAME = 'ZenSoSo'

def recent_files():
	def sync(items):
		settings().setValue("recent_files", items)
	if not hasattr(recent_files, 'list'):
		recent_files.list = RecentFilesList(settings().value("recent_files", []))
		recent_files.list.on_change(sync)
	return recent_files.list

def settings():
	if not hasattr(settings, 'object'):
		settings.object = QSettings(VENDOR_NAME, __package__)
	return settings.object

class Window(QMainWindow):

	def __init__(self):
		super().__init__()
		self.menuOpen_Recent.aboutToShow.connect(self.fill_recent_file_menu)

	@pyqtSlot()
	def fill_recent_file_menu(self):
		self.menuOpen_Recent.clear()
		actions = []
		for filename in recent_files().prune():
			action = QAction(filename, self)
			action.triggered.connect(partial(self.load_file, filename))
			actions.append(action)
		self.menuOpen_Recent.addActions(actions)

	def load_file(self, filename):
		self.recent_files.bump(filename)

```

