---
title: Text Snippets
description: Reusable text values from inline, file, command, or directory sources
---
import { Aside, Tabs, TabItem, Card, CardGrid, Steps } from '@astrojs/starlight/components';
The native interface supports text snippets, which let you define reusable text values that can be searched and copied to the clipboard or typed into applications.
<Aside type="note">
Text snippets are only available in **native mode**. They are not available when using Fuzzel mode.
</Aside>
Snippets can come from four different sources:
<div class="nav-cards">
<CardGrid>
<a href="#inline-snippets">
<Card title="Inline" icon="pencil">
Defined directly in the config file
</Card>
</a>
<a href="#file-source">
<Card title="File" icon="document">
Loaded from an external YAML file
</Card>
</a>
<a href="#command-source">
<Card title="Command" icon="laptop">
Generated by running a command (Alfred JSON format)
</Card>
</a>
<a href="#directory-source">
<Card title="Directory" icon="puzzle">
Loaded from `.snippet` files in a directory
</Card>
</a>
</CardGrid>
</div>
<style>
{`
.nav-cards a {
text-decoration: none !important;
color: inherit;
display: flex;
height: 100%;
}
.nav-cards a article {
flex: 1;
transition: all 0.2s ease-in-out;
cursor: pointer;
display: flex;
flex-direction: column;
gap: 1rem;
border: 1px solid var(--sl-color-gray-5);
background-color: var(--sl-color-black);
}
.nav-cards a article .title {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 1rem;
font-size: 1.2rem;
}
.nav-cards a article .title .icon {
font-size: 2.5rem !important; /* Huge icons */
color: var(--sl-color-purple);
background: var(--sl-color-purple-low);
padding: 0.5rem;
border-radius: 0.5rem;
border: 1px solid var(--sl-color-purple);
}
.nav-cards a:hover article {
border-color: var(--sl-color-text-accent);
background-color: var(--sl-color-gray-6);
}
`}
</style>
<Steps>
1. **Type Keyword**
Type the configured keyword followed by a space (e.g., `em ` for emails).
While you are still typing the keyword, Raffi shows a row describing what it
does; press Enter or Tab on that row to jump straight into the source.
2. **Filter Results**
Continue typing to fuzzy-filter snippets by name
3. **Select Snippet**
Use arrow keys to select the desired snippet
4. **Execute Action**
- **Enter**: Default action (copy or insert)
- **Ctrl+Enter**: Secondary action (if configured)
</Steps>
Define snippets directly in `raffi.yaml`:
```yaml raffi.yaml
addons:
text_snippets:
- name: "Emails"
keyword: "em"
icon: "mail"
snippets:
- name: "Personal Email"
value: "user@example.com"
- name: "Work Email"
value: "user@company.com"
- name: "Support Email"
value: "support@company.com"
```
Usage:
```text
em personal
```
Load snippets from an external YAML file:
```yaml raffi.yaml
addons:
text_snippets:
- name: "Templates"
keyword: "tpl"
icon: "document"
file: "~/.config/raffi/snippets.yaml"
```
The snippet file (`~/.config/raffi/snippets.yaml`):
```yaml snippets.yaml
- name: "Greeting"
value: "Hello, world!"
- name: "Signature"
value: "Best regards, User"
- name: "Meeting Template"
value: |
Meeting Notes
Date: [DATE]
Attendees: [NAMES]
Topics:
-
Action Items:
-
```
<Aside type="note">
File-based snippets are cached per session for performance.
</Aside>
Generate snippets dynamically from a command:
```yaml raffi.yaml
addons:
text_snippets:
- name: "Dynamic"
keyword: "dyn"
icon: "terminal"
command: "my-snippet-gen"
args: ["-j"]
```
The command must output JSON in Alfred Script Filter format:
```json
{
"items": [
{
"title": "Current Date",
"arg": "2024-03-15"
},
{
"title": "Current Time",
"arg": "14:30:00"
}
]
}
```
<Aside type="tip">
The `title` field becomes the snippet name, and `arg` becomes the snippet value.
</Aside>
Load snippets from a directory of `.snippet` files:
```yaml raffi.yaml
addons:
text_snippets:
- name: "Snippets"
keyword: "sn"
icon: "snippets"
directory: "~/.local/share/desktop-config/snippets"
```
Each `.snippet` file has this format:
```text greeting.snippet
Friendly Greeting
---
Hello! How are you doing today?
```
```text email-signature.snippet
Professional Signature
---
Best regards,
John Doe
Software Engineer
john@example.com
```
Format:
- **First line**: Snippet name (description)
- **`---`**: Separator
- **After separator**: Snippet content (value)
<Aside type="note">
Directory-based snippets are sorted alphabetically and cached per session.
</Aside>
Configure how snippets are used when selected:
<Tabs>
<TabItem label="Copy (Default)">
```yaml
action: "copy"
```
Copies snippet to clipboard using `wl-copy`, `xclip`, or `xsel`
</TabItem>
<TabItem label="Insert/Type">
```yaml
action: "insert"
```
Types snippet into focused app using `wtype` or `ydotool`
</TabItem>
</Tabs>
Use command templates with `{value}` placeholder:
```yaml raffi.yaml
text_snippets:
- name: "Commands"
keyword: "cmd"
action: "kitty sh -c {value}"
snippets:
- name: "System Update"
value: "sudo pacman -Syu"
```
Configure different actions for Enter and Ctrl+Enter:
```yaml raffi.yaml
text_snippets:
- name: "Emails"
keyword: "em"
icon: "mail"
action: "insert" secondary_action: "copy" snippets:
- name: "Personal Email"
value: "user@example.com"
- name: "Work Email"
value: "user@company.com"
```
**`name`** `string` (required)
Display name shown during loading (for command sources)
**`keyword`** `string` (required)
Text that activates the snippet source
**`icon`** `string`
Icon name from your icon cache to display next to each snippet
**`snippets`** `array`
Inline list of snippets (each with `name` and `value`)
**`file`** `string`
Path to a YAML file containing snippets (cached per session)
**`command`** `string`
Executable that outputs Alfred Script Filter JSON
**`directory`** `string`
Path to a directory of `.snippet` files (cached per session)
**`args`** `array`
Arguments passed to the command
**`action`** `string` (default: `copy`)
Action on Enter:
- `"copy"`: Copy to clipboard
- `"insert"`: Type into focused app
- Command template with `{value}` placeholder
**`secondary_action`** `string` (default: `insert`)
Action on Ctrl+Enter. Accepts same values as `action`.
<Aside type="caution">
Exactly one of `snippets`, `file`, `command`, or `directory` should be specified per entry.
</Aside>
```yaml raffi.yaml
text_snippets:
- name: "Emails"
keyword: "em"
icon: "mail"
snippets:
- name: "Personal"
value: "john@personal.com"
- name: "Work"
value: "john@company.com"
- name: "GitHub"
value: "john@users.noreply.github.com"
```
```yaml raffi.yaml
text_snippets:
- name: "Code Templates"
keyword: "code"
icon: "code"
action: "insert"
snippets:
- name: "Rust Main"
value: |
fn main() {
println!("Hello, world!");
}
- name: "Python Main"
value: |
if __name__ == "__main__":
pass
```
```yaml raffi.yaml
text_snippets:
- name: "Git Commands"
keyword: "git"
file: "~/.config/raffi/git-snippets.yaml"
```
```yaml git-snippets.yaml
- name: "Amend Commit"
value: "git commit --amend --no-edit"
- name: "Push Force"
value: "git push --force-with-lease"
- name: "Interactive Rebase"
value: "git rebase -i HEAD~"
```
Create a script that generates date snippets:
```python date-snippets.py
import json
from datetime import datetime, timedelta
today = datetime.now()
items = [
{"title": "Today", "arg": today.strftime("%Y-%m-%d")},
{"title": "Yesterday", "arg": (today - timedelta(days=1)).strftime("%Y-%m-%d")},
{"title": "Tomorrow", "arg": (today + timedelta(days=1)).strftime("%Y-%m-%d")},
{"title": "ISO Timestamp", "arg": today.isoformat()},
]
print(json.dumps({"items": items}))
```
```yaml raffi.yaml
text_snippets:
- name: "Dates"
keyword: "date"
command: "python3 ~/.config/raffi/date-snippets.py"
icon: "calendar"
```
<details>
<summary>Contact Information</summary>
```yaml
- name: "Contact"
keyword: "contact"
snippets:
- name: "Email"
value: "user@example.com"
- name: "Phone"
value: "+1-555-0123"
- name: "Address"
value: "123 Main St, City, State 12345"
```
</details>
<details>
<summary>Frequently Used Commands</summary>
```yaml
- name: "Shell Commands"
keyword: "sh"
action: "insert"
snippets:
- name: "Docker Cleanup"
value: "docker system prune -af"
- name: "Find Large Files"
value: "du -sh * | sort -h"
```
</details>
<details>
<summary>Text Templates</summary>
```yaml
- name: "Templates"
keyword: "tpl"
directory: "~/.config/raffi/templates"
```
With files like:
- `meeting-notes.snippet`
- `bug-report.snippet`
- `email-signature.snippet`
</details>
<details>
<summary>Programming Snippets</summary>
```yaml
- name: "Code"
keyword: "snippet"
file: "~/.config/raffi/code-snippets.yaml"
action: "insert"
```
</details>
- **Enter**: Execute primary action (default: copy)
- **Ctrl+Enter**: Execute secondary action (default: insert)
- **Esc**: Cancel and return to normal mode
- **↑/↓**: Navigate through snippets
<Aside type="note">
**For copying**: `wl-copy` (wl-clipboard), `xclip`, or `xsel`
</Aside>
<Aside type="note">
**For typing/inserting**: `wtype` or `ydotool`
</Aside>
<Aside type="tip">
Use file sources for large snippet collections to keep your main config clean
</Aside>
<Aside type="tip">
Command sources are perfect for dynamic content like dates, git branch names, or API responses
</Aside>
<Aside type="tip">
Directory sources work well for organizing snippets by category (each category in its own directory)
</Aside>
<Aside type="tip">
Set `action: "insert"` and `secondary_action: "copy"` for maximum flexibility
</Aside>
Here's a full configuration with multiple snippet sources:
```yaml raffi.yaml
addons:
text_snippets:
- name: "Emails"
keyword: "em"
icon: "mail"
action: "copy"
snippets:
- name: "Personal"
value: "user@example.com"
- name: "Work"
value: "user@company.com"
- name: "Templates"
keyword: "tpl"
icon: "document"
file: "~/.config/raffi/templates.yaml"
action: "insert"
- name: "Dates"
keyword: "date"
command: "date-snippets"
icon: "calendar"
- name: "Code Snippets"
keyword: "code"
directory: "~/.config/raffi/snippets"
action: "insert"
secondary_action: "copy"
```