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:
- Variable detection — Scans for
{{…}}syntax; returns raw text if none found - Date/time interpolation — Replaces
{{date}},{{time}}, and{{datetime}}with locale-aware strings viaDateFormatter - Formatted date handling — Processes custom patterns like
{{date:yyyy-MM-dd}}or{{date-tz(America/New_York):yyyy-MM-dd}}throughexpandingFormattedDates - 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:
- Definition — Users create snippets in
SnippetEditor(presented fromTextSnippetsSettings), which displays variable guidance throughvariablesHint,variablesCaption, andvariablesFormatCaptionproperties around lines 82-87 - Persistence — Upon saving at lines 59-67,
TextSnippetSupport.encodeserializes snippets toUserDefaultsafter sanitizing triggers and trimming whitespace - Synchronization —
TextSnippetService.shared.syncWithPreferences()reloads the snippet cache immediately after persistence so subsequent keystrokes use updated definitions - Runtime expansion — Keystrokes append to the buffer until
matchdetects a valid trigger, callingexpandwith the currentclipboardstring 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, withmatchselecting the longest valid trigger using case-sensitive or case-insensitive comparison - Clipboard variables use the
{{clipboard}}syntax, resolved duringexpandafter date processing to prevent recursive expansion - The
needsClipboard(_:)helper prevents unnecessary pasteboard reads when snippets don't contain clipboard tokens - Snippets persist through
UserDefaultsviaTextSnippetSupport.encode, with immediate synchronization throughTextSnippetService.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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →