# How Text Snippet Expansion Works with Clipboard Variables in Vorssaint-Utils

> Discover how vorssaint-utils text snippet expansion uses a circular buffer to replace trigger strings with templates, inserting clipboard contents via {{clipboard}} variables.

- Repository: [vorssaint/vorssaint-utils](https://github.com/vorssaint/vorssaint-utils)
- Tags: how-to-guide
- Published: 2026-09-11

---

**Vorssaint-Utils implements text snippet expansion through a 64-character circular buffer that matches trigger strings and replaces them with templates containing variables like `{{clipboard}}`, which injects current pasteboard contents at expansion time.**

Vorssaint-Utils is an open-source Swift utility library that provides deterministic, testable text snippet expansion with support for dynamic variables. The system processes keystrokes in real-time through the `TextSnippetSupport` engine, matching user-defined triggers and expanding them into full replacement strings that can incorporate clipboard contents, dates, and custom formatting patterns according to the source code in [`Sources/Vorssaint/Services/Snippets/TextSnippetSupport.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/Sources/Vorssaint/Services/Snippets/TextSnippetSupport.swift).

## Core Architecture: TextSnippetSupport Engine

The expansion logic resides in [`Sources/Vorssaint/Services/Snippets/TextSnippetSupport.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/Sources/Vorssaint/Services/Snippets/TextSnippetSupport.swift), which serves as the pure logic layer independent of the UI. This architecture separates matching algorithms from interface concerns, enabling comprehensive unit testing of snippet behavior while the UI layer (`TextSnippetsSettings` and `SnippetEditor`) handles user interaction.

### Buffer Management and Trigger Detection

Each keystroke appends to a circular buffer via `bufferAppending`, maintaining a maximum history of **64 characters** defined in the circular buffer implementation. When the buffer contents require evaluation, the `match(buffer:expansion:snippets:)` function scans enabled snippets to find the longest trigger matching the buffer suffix. The `completes(_:trigger:ignoresCase:)` method performs optional case-insensitive matching based on the snippet's `ignoresCase` configuration, checking if the buffer ends with the trigger string.

### The Expansion Pipeline

Once matched, `expand(_:date:clipboard:locale:)` processes the replacement string through a deterministic sequence:

1. **Variable detection** — Scans for `{{…}}` syntax; returns raw text if none found
2. **Date/time interpolation** — Replaces `{{date}}`, `{{time}}`, and `{{datetime}}` with locale-aware strings via `DateFormatter`
3. **Formatted date handling** — Processes custom patterns like `{{date:yyyy-MM-dd}}` or `{{date-tz(America/New_York):yyyy-MM-dd}}` through `expandingFormattedDates`
4. **Clipboard substitution** — Injects pasteboard contents as the final step to prevent re-expansion of pasted text containing braces

## Clipboard Variable Implementation

Clipboard integration follows a defensive design that prevents application crashes when pasteboard access is unavailable or restricted.

### The {{clipboard}} Token Syntax

Users insert `{{clipboard}}` anywhere within a snippet's replacement text. During expansion, this token resolves to the current pasteboard string passed from the UI layer via the `clipboard` parameter, or an empty string if clipboard access fails. The `needsClipboard(_:)` helper at lines 12-15 optimizes performance by checking for token presence before the UI layer executes any pasteboard read operations.

### Safe Clipboard Resolution

The expansion engine guarantees that clipboard injection occurs after all date processing completes at lines 43-46. This ordering ensures that clipboard contents containing brace characters or date-like strings won't trigger secondary expansions. If the pasteboard is empty or inaccessible, the token substitutes to an empty string rather than null, maintaining template integrity without throwing errors.

## Complete Workflow from Keystroke to Expansion

The runtime flow spans both service logic and UI components defined in [`Sources/Vorssaint/UI/Settings/TextSnippetsSettings.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/Sources/Vorssaint/UI/Settings/TextSnippetsSettings.swift):

1. **Definition** — Users create snippets in `SnippetEditor` (presented from `TextSnippetsSettings`), which displays variable guidance through `variablesHint`, `variablesCaption`, and `variablesFormatCaption` properties around lines 82-87
2. **Persistence** — Upon saving at lines 59-67, `TextSnippetSupport.encode` serializes snippets to `UserDefaults` after sanitizing triggers and trimming whitespace
3. **Synchronization** — `TextSnippetService.shared.syncWithPreferences()` reloads the snippet cache immediately after persistence so subsequent keystrokes use updated definitions
4. **Runtime expansion** — Keystrokes append to the buffer until `match` detects a valid trigger, calling `expand` with the current `clipboard` string obtained from the system pasteboard

## Practical Implementation Examples

### Basic Clipboard Injection

```swift
// Define a snippet (normally done through the UI)
let clipboardSnippet = TextSnippet(
    name: "Paste‑URL",
    trigger: ";url",
    replacement: "{{clipboard}}",          // ← clipboard token
    expansion: .immediate,                // fires as soon as trigger ends
    enabled: true,
    ignoresCase: false,
    folder: "",
    showsInLibrary: true
)

// Simulate typing ";url"
var buffer = ""
buffer = TextSnippetSupport.bufferAppending(buffer, typed: ";")
buffer = TextSnippetSupport.bufferAppending(buffer, typed: "u")
buffer = TextSnippetSupport.bufferAppending(buffer, typed: "r")
buffer = TextSnippetSupport.bufferAppending(buffer, typed: "l")

if let match = TextSnippetSupport.match(
        buffer: buffer,
        expansion: .immediate,
        snippets: [clipboardSnippet]) {
    // Assume the clipboard currently holds "https://example.com"
    let expanded = TextSnippetSupport.expand(
        match.replacement,
        date: Date(),
        clipboard: "https://example.com")
    print(expanded)   // → https://example.com
}

```

### Combining Date and Clipboard Variables

```swift
let mixedSnippet = TextSnippet(
    name: "Log entry",
    trigger: ";log",
    replacement: "{{date}} – {{clipboard}}",
    expansion: .afterDelimiter,
    enabled: true,
    ignoresCase: true,
    folder: "",
    showsInLibrary: true)

// User types ";log " (note trailing space triggers after‑delimiter)
let buffer = TextSnippetSupport.bufferAppending(";log ", typed: "")
if let match = TextSnippetSupport.match(buffer: buffer,
                                         expansion: .afterDelimiter,
                                         snippets: [mixedSnippet]) {
    let result = TextSnippetSupport.expand(match.replacement,
                                            date: Date(),
                                            clipboard: "User clicked button")
    // Example output: "Oct 12, 2026 – User clicked button"
    print(result)
}

```

## Summary

- **Vorssaint-Utils** implements snippet expansion through a pure logic layer (`TextSnippetSupport`) separate from UI concerns, enabling testable macro functionality
- The **64-character circular buffer** tracks keystrokes via `bufferAppending`, with `match` selecting the longest valid trigger using case-sensitive or case-insensitive comparison
- **Clipboard variables** use the `{{clipboard}}` syntax, resolved during `expand` after date processing to prevent recursive expansion
- The `needsClipboard(_:)` helper prevents unnecessary pasteboard reads when snippets don't contain clipboard tokens
- Snippets persist through `UserDefaults` via `TextSnippetSupport.encode`, with immediate synchronization through `TextSnippetService.shared.syncWithPreferences()`

## Frequently Asked Questions

### What happens if the clipboard is empty when a snippet expands?

If the system pasteboard contains no data or the application lacks clipboard access permissions, the `{{clipboard}}` token resolves to an empty string rather than causing a crash or returning null. The `expand(_:date:clipboard:locale:)` method accepts an optional clipboard parameter and substitutes an empty string when the value is unavailable, ensuring the rest of the replacement text remains intact.

### Can I use multiple clipboard variables in one snippet?

Yes, you can insert multiple `{{clipboard}}` tokens throughout a single replacement string. Each instance receives the same current clipboard contents when `expand` processes the template. There is no limit to token quantity within the replacement field, though all instances resolve to the identical pasteboard content captured at expansion time.

### How does case sensitivity affect snippet matching?

Each snippet stores an `ignoresCase` boolean property. When `match(buffer:expansion:snippets:)` evaluates triggers, it passes this flag to `completes(_:trigger:ignoresCase:)`. If enabled, the buffer suffix comparison uses case-insensitive matching; otherwise, it requires exact case matching. This allows triggers like ";email" to match whether the user types ";EMAIL" or ";email" based on configuration.

### Where does Vorssaint-Utils store snippet definitions?

Snippet definitions persist to `UserDefaults` through `TextSnippetSupport.encode`, which sanitizes triggers by trimming whitespace before serialization. The `TextSnippetService` reloads these definitions immediately after persistence via `syncWithPreferences()`, ensuring the 64-character keystroke buffer references current data without requiring application restarts.