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

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.

Core Architecture: TextSnippetSupport Engine

The expansion logic resides in 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:

  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

// 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

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.

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 →