How Clipboard History Manages Pinned Favorites and Search in vorssaint-utils

The clipboard history system in vorssaint-utils separates pinned favorites from recent items using a dual-section array managed by ClipboardHistoryService, while search employs a normalized, tokenized ranking algorithm that prioritizes pinned entries with a +30 bonus and scores matches by exact, prefix, and token relevance.

The vorssaint-utils repository provides a robust clipboard management system implemented in Swift that handles persistent storage, automatic eviction, and intelligent search. Understanding how the codebase separates pinned favorites from transient history items—and how it ranks search results—requires examining the interplay between ClipboardHistoryService.swift and ClipboardHistorySupport.swift.

Architecture Overview

The clipboard history implementation divides responsibilities between two primary files in Sources/Vorssaint/Services/Clipboard/. The service layer manages the mutable entry list and UI state, while the support layer defines the data models and search algorithms.

This separation allows the search algorithm to remain pure and testable while the service handles side effects like persistence and memory management.

Pinning Logic and Entry Management

Entry Model and Pinned State

Each clipboard item is represented by ClipboardHistoryEntry in ClipboardHistorySupport.swift (lines 12‑30). The model tracks pinned status through an optional pinnedAt timestamp:

// Conceptual representation from ClipboardHistorySupport.swift
struct ClipboardHistoryEntry {
    let id: UUID
    let content: String
    let timestamp: Date
    var pinnedAt: Date?  // nil = not pinned, Date = pinned with ordering
}

When pinnedAt is non-nil, the entry belongs to the favorites section. The timestamp itself determines relative order among pinned items.

Toggle Pin Mechanism

The togglePin(_:) method in ClipboardHistoryService.swift (lines 39‑52) handles state transitions. When pinning an entry, the method moves it to the front of the internal array immediately after the last pinned item. When unpinning, it relocates the entry to the first position of the recent section.

After any modification, the service triggers normalizeEntryOrder() to ensure the array maintains the invariant: all pinned entries precede recent entries, sorted by pinnedAt descending within the pinned group.

Persistence and Limits

Following normalization, trimToLimit() enforces the maximum history size. Critically, pinned entries are exempt from eviction during this trimming phase. The service persists the final array to disk, ensuring favorites survive app relaunches.

Accessing the separated lists is handled through computed properties exposed on the service:

// In ClipboardHistoryService.swift (lines 11‑18)
let favorites = ClipboardHistoryService.shared.pinnedEntries   // Array of pinned items
let recent = ClipboardHistoryService.shared.recentEntries    // Array of unpinned items

Search and Ranking Algorithm

Query Processing and Normalization

The entry point for search is filteredEntries(matching:) in ClipboardHistoryService.swift (lines 90‑100). This method maintains an internal cache of the current query string to avoid recomputation across rapid UI updates.

Before scoring, both the query and entry content undergo normalization via normalized(_:) in ClipboardHistorySupport.swift. This folding process removes diacritics and converts text to a canonical case-insensitive form, ensuring "résumé" matches "resume".

The normalized query is then tokenized on whitespace into queryTokens, allowing multi-word searches to match individual components anywhere in the entry text.

Scoring System

The heavy lifting occurs in ClipboardHistorySearch.rankedIndexes(...) (lines 25‑48 of ClipboardHistorySupport.swift). The algorithm evaluates each entry through score(for:text:normalizedQuery:tokens:isPinned:) (lines 58‑78), which applies the following hierarchy:

Base Score Modifiers:

  • Pinned bonus: +30 points if isPinned is true
  • Exact match: Highest additional score when query equals entry text exactly
  • Prefix match: High score when entry text starts with the query
  • Token match: Moderate score for each token found anywhere in the text
  • Substring match: Lowest score for simple containment

This weighted approach ensures that a pinned entry containing a token match outranks an unpinned entry with an exact match, keeping favorites visible even with imperfect search terms.

Result Ordering

After scoring, candidates are sorted by descending score and original index to maintain stability. The method returns entry indexes that the service transforms back into ClipboardHistoryEntry objects for UI rendering.

Implementation Example

Integrating these features into a macOS or iOS application requires minimal boilerplate:

// Pin or un-pin an entry from user interaction
ClipboardHistoryService.shared.togglePin(selectedEntry)

// Retrieve favorites for a dedicated "Pinned" sidebar section
let pinnedItems = ClipboardHistoryService.shared.pinnedEntries

// Perform live search with relevance ranking
// Results automatically include both pinned and recent items, sorted by score
let searchResults = ClipboardHistoryService.shared.filteredEntries(matching: "swift image")

The service automatically manages the cache invalidation, ensuring that subsequent calls with the same query return immediately without recomputing the ranking.

Summary

  • ClipboardHistoryEntry tracks pinned state via an optional pinnedAt timestamp in ClipboardHistorySupport.swift.
  • togglePin(_:) moves entries between the pinned and recent sections, followed by normalizeEntryOrder() to maintain array invariants.
  • Pinned entries receive priority placement at the front of the list and are protected from eviction during trimToLimit().
  • Search normalization removes case and diacritic sensitivity before tokenizing the query on whitespace.
  • Ranking algorithm adds a +30 bonus to pinned items and scores matches by exact, prefix, token, and substring relevance in ClipboardHistorySearch.rankedIndexes(...).
  • Public API exposes pinnedEntries, recentEntries, and filteredEntries(matching:) for UI consumption without exposing internal array management.

Frequently Asked Questions

How does vorssaint-utils ensure pinned clipboard items persist across app restarts?

The ClipboardHistoryService persists the entire entry array—including the pinnedAt timestamps—to disk after every mutation. Because pinned entries are stored with their metadata intact, they reload in the correct order when the service initializes, maintaining the separation between favorites and recent items.

What happens when the clipboard history reaches its size limit?

The trimToLimit() method removes oldest entries from the recent section only. Pinned entries are exempt from this eviction logic, ensuring that favorited clipboard items never disappear automatically, regardless of how many new items are copied.

Why do pinned entries appear higher in search results even with weak matches?

The scoring algorithm in ClipboardHistorySearch applies a +30 base bonus to all pinned entries before evaluating text matches. This weighting ensures that a pinned entry with a token match outranks an unpinned entry with an exact match, preserving quick access to favorites during search.

How does the search handle special characters and accented text?

Both queries and entry content are processed through the normalized(_:) function, which performs case folding and diacritic removal. Consequently, searching for "resume" matches "résumé", and the tokenization splits on whitespace to handle multi-word queries gracefully.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →