# How Text Snippet Triggering Works in Vorssaint-utils: Implementation and Architecture

> Learn how text snippet triggering works in vorssaint-utils. Discover the implementation details of event tapping, character buffering, and trigger expansion using synthetic key events or clipboard operations.

- Repository: [vorssaint/vorssaint-utils](https://github.com/vorssaint/vorssaint-utils)
- Tags: implementation-and-architecture
- Published: 2026-09-12

---

**Vorssaint-utils implements text snippet triggering by installing a low-level macOS event tap that intercepts key-down events, accumulates typed characters in a thread-local buffer, and expands matched triggers through synthetic key events or transient clipboard paste operations.**

Text snippet triggering in vorssaint/vorssaint-utils provides system-wide text expansion across macOS applications. The implementation centers on [`TextSnippetService.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/TextSnippetService.swift), which orchestrates event monitoring, trigger detection, and content injection while coordinating with helper utilities in [`TextSnippetSupport.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/TextSnippetSupport.swift).

## Event Tap Architecture and Text Snippet Triggering Lifecycle

The `TextSnippetService` operates as a singleton (`TextSnippetService.shared`) that initializes at application launch and registers for session state changes via `SessionActivity.shared.onChange`.

### Initializing the Singleton Service

During `init`, the service establishes a callback with `SessionActivity` to synchronize with user preferences. The `syncWithPreferences()` method—implemented in lines 12-44 of [`TextSnippetService.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/TextSnippetService.swift)—checks whether text snippets are enabled, loads stored definitions from `UserDefaults` under `DefaultsKey.textSnippets`, and determines if the event tap should activate based on `SessionActivitySupport.tapShouldRun`. According to the source code, if the snippet library or command bar UI is visible, the input buffer clears immediately to prevent accidental expansions during navigation (lines 52-58).

### Creating the CGEvent Tap

When activated, `runEventTap()` creates a system-wide tap using `CGEvent.tapCreate` that monitors `keyDown`, `leftMouseDown`, and `rightMouseDown` events (lines 43-61). The tap callback forwards each event to `handle(type:event:)` for processing. This architecture ensures every keystroke passes through the service's filtering logic before reaching the target application, enabling real-time text snippet triggering across all applications.

## Buffer Management During Text Snippet Recognition

The service maintains a thread-local `buffer` that accumulates typed characters sequentially, enabling substring matching against configured triggers.

### Accumulation and Reset Conditions

The buffer appends characters during normal typing but resets under specific conditions to prevent inappropriate expansions:

- Mouse clicks occurring outside the AssistiveKeyboard area
- Modifier key presses (⌘ or ⌃)
- Activation of secure input fields
- Visibility changes in the Snippet Library or Command Bar interfaces

These guards, implemented in lines 57-67, ensure that text snippet triggering does not interfere with secure password fields or UI navigation.

## Trigger Matching for Text Snippet Expansion

Vorssaint-utils supports two distinct triggering mechanisms that determine when expansion occurs relative to typing patterns.

### Immediate vs After-Delimiter Triggers

**Immediate** triggers fire as soon as the complete trigger string is typed—for example, typing `;email` instantly expands to the configured replacement. **After-Delimiter** triggers activate only when a delimiter character (`;`, `,`, `.`, etc.) follows the trigger string, allowing the service to swallow the delimiter, expand the content, and re-insert the delimiter afterward.

At load time, `TextSnippetService` splits snippets into `immediateSnippets` and `delimiterSnippets` arrays (lines 33-38) to optimize lookup performance.

### The Matching Algorithm

Matching occurs through `TextSnippetSupport.match(buffer:expansion:snippets:)` (lines 90-99), which respects the `ignoresCase` property of each snippet definition. The function returns the first matching snippet found in the buffer, enabling priority-based expansion when multiple triggers might overlap.

## Snippet Expansion and Delivery Methods

Once a match occurs, the service executes a multi-stage expansion pipeline that handles variable substitution and text injection.

### Variable Resolution

The `TextSnippetSupport.expand` utility processes replacement strings containing placeholders like `{{datetime}}`, `{{date}}`, `{{time}}`, and `{{clipboard}}`, substituting current values before injection. This resolution happens after trigger detection but before the final output delivery.

### Synthetic Keys vs Transient Paste

The service chooses between two delivery methods based on content characteristics:

1. **Synthetic key events**: Used for single-line text without special formatting, injected as UTF-16 units (maximum approximately 20 per event) to preserve clipboard contents
2. **Transient clipboard paste**: Invoked via `TransientPaste.shared.paste` when `TextSnippetSupport.requiresPaste` determines the content contains newline characters or exceeds typing efficiency thresholds, temporarily preserving the original clipboard content during the paste operation

The `deleteCount` parameter determines how many backspace operations clear the original trigger text before insertion.

## Safety Mechanisms in Text Snippet Execution

The implementation includes specific safeguards to prevent feedback loops and inappropriate expansions.

### Synthetic Event Protection

All synthetic events generated by the service carry a fixed marker value to prevent recursive processing. The constant is defined as:

```swift
private static let syntheticMarker: Int64 = 0x564F5253

```

This value corresponds to ASCII "VORS". The event tap callback checks for this marker (lines 47-50) and ignores any events containing it, ensuring the service never attempts to expand text it just injected.

### UI Coordination and Visibility Guards

The service maintains visibility flags via `SnippetLibraryService.shared.isVisible` and `CommandBarService.shared.isVisible`. When either interface is active, the buffer clears automatically, ensuring that browsing the snippet library or invoking the command bar does not accidentally trigger expansions based on navigation keystrokes.

## Practical Implementation Examples

The following examples demonstrate how to define and trigger snippets using the Vorssaint-utils API.

### Defining a Basic Snippet

```swift
let emailSnippet = TextSnippet(
    name: "Email",
    trigger: ";email",
    replacement: "me@mydomain.com",
    expansion: .immediate,
    ignoresCase: false,
    enabled: true
)
UserDefaults.standard.set(
    TextSnippetSupport.encode([emailSnippet]),
    forKey: DefaultsKey.textSnippets
)

```

### Configuring After-Delimiter Expansion

```swift
let dateSnippet = TextSnippet(
    name: "Now",
    trigger: ";;dt",
    replacement: "{{datetime}}",
    expansion: .afterDelimiter,
    ignoresCase: true,
    enabled: true
)

```

When the user types `;;dt;` (with the final `;` as delimiter), the service detects the delimiter, matches the after-delimiter snippet, expands the date-time variable, and re-inserts the delimiter.

## Summary

- **Vorssaint-utils** implements text snippet triggering through a macOS CGEvent tap installed by [`TextSnippetService.swift`](https://github.com/vorssaint/vorssaint-utils/blob/main/TextSnippetService.swift) that monitors global key-down events via `CGEvent.tapCreate`
- A thread-local buffer accumulates keystrokes and resets on mouse clicks, modifier keys, secure input, or UI visibility changes to prevent accidental expansions
- Two trigger modes exist: **Immediate** (instant expansion) and **After-Delimiter** (expansion following punctuation), with snippets categorized at load time into `immediateSnippets` and `delimiterSnippets` for efficient lookup
- Expansion supports variable substitution (`{{datetime}}`, `{{clipboard}}`) and chooses between synthetic key injection or `TransientPaste.shared.paste` based on content complexity
- Synthetic events carry the marker `0x564F5253` ("VORS") to prevent recursive processing, while UI guards ensure the library and command bar interfaces don't trigger accidental expansions

## Frequently Asked Questions

### How does Vorssaint-utils prevent text snippet triggering in password fields?

The service monitors system security states and clears the internal buffer whenever secure input becomes active. Additionally, the CGEvent tap implementation respects macOS secure input protections, automatically disabling monitoring in password fields and other protected contexts to prevent keystroke logging of sensitive data.

### What happens when a snippet replacement contains multiple lines?

When `TextSnippetSupport.requiresPaste` determines the content contains newline characters or complex formatting unsuitable for keystroke simulation, the service invokes `TransientPaste.shared.paste`. This method temporarily stores the current clipboard content, pastes the snippet replacement, and restores the original clipboard, ensuring complex expansions render correctly without permanently overwriting the user's clipboard.

### Can two snippets share the same trigger prefix without conflicting?

Yes, the matching system processes buffers against both `immediateSnippets` and `delimiterSnippets` arrays independently. The `TextSnippetSupport.match` function returns the first match found, allowing longer triggers to coexist with shorter prefixes (e.g., `;email` and `;emailwork`) provided they are defined with distinct full trigger strings. The order of definition determines priority when buffers match multiple patterns.

### How does the service distinguish between user typing and its own synthetic inputs?

Every synthetic event generated during expansion includes the marker `0x564F5253` in its metadata. The `handle(type:event:)` method checks for this `syntheticMarker` constant and immediately returns unprocessed events that contain it. This prevents the service from attempting to expand text it just injected, eliminating infinite loop scenarios where expanded content might match another trigger.