Skip to main content
Shortcuts in Memos help you work faster by saving frequently used filters and providing keyboard shortcuts for common actions.

Filter Shortcuts

Filter shortcuts save complex CEL expressions for instant access.

Creating a Shortcut

1

Open the Create Dialog

Click the + New Shortcut button in the sidebar (visible on Home page).
2

Enter Title

Choose a descriptive title. Emoji are supported and recommended:
💼 Work TODOs
✅ Completed Tasks
👥 Team Updates
📊 Weekly Reports
3

Write Filter Expression

Enter a CEL filter expression:
tag_search == "work" && property.has_incomplete_tasks == true
The filter is validated before saving.
4

Save

Click Save to create the shortcut. It appears immediately in your sidebar.

Using Shortcuts

  1. Click a shortcut in the sidebar
  2. Memos are filtered instantly
  3. The shortcut highlights to show it’s active
  4. Click again to deactivate and clear the filter
Shortcuts are exclusive - activating one deactivates others.

Managing Shortcuts

Update existing shortcuts:
  1. Click the menu icon (three dots) next to the shortcut
  2. Select Edit
  3. Modify the title or filter
  4. Save changes
The shortcut updates immediately for all active sessions.

Shortcut Examples

Here are practical shortcut filters you can use:

Personal Productivity

Find incomplete tasks for today:
property.has_incomplete_tasks == true
Find urgent and high-priority items:
tag_search == "urgent" || tag_search == "high-priority"
Show only pinned memos:
pinned == true
Memos from the current week:
create_time > timestamp("2024-01-20T00:00:00Z")
Update the timestamp each week, or use relative timestamps if your implementation supports them.

Work & Projects

All work-related memos:
tag_search == "work" || tag_search.startsWith("work/")
Memos for active projects:
(tag_search == "project/alpha" || tag_search == "project/beta") &&
!(tag_search == "archived")
Team-related memos and meetings:
tag_search == "team" || tag_search == "meeting" || tag_search == "standup"
All meeting notes:
tag_search == "meeting" || tag_search == "meeting-notes"

Learning & Knowledge

Memos with links to read:
tag_search == "reading" && property.has_link == true
Memos containing code:
property.has_code == true
Educational content and tutorials:
tag_search == "learning" || tag_search == "tutorial" || tag_search == "til"
Public memos with links:
visibility == "PUBLIC" && property.has_link == true

Content Types

All memos with task lists:
property.has_task_list == true
Your private memos only:
visibility == "PRIVATE"
Publicly shared content:
visibility == "PUBLIC"
Memos with attachments (approximate via tags):
tag_search == "image" || tag_search == "photo"
Direct attachment filtering is not yet exposed in CEL. Tag images for now.

Keyboard Shortcuts

Boost productivity with keyboard shortcuts in the editor.

Editor Shortcuts

ActionShortcut
Save memoCmd + Enter
Bold textCmd + B
Italic textCmd + I
Insert linkCmd + K
Insert codeCmd + E
Toggle focus modeCmd + Shift + F
Cancel editingEsc

Slash Commands

Type / in the editor to access quick insertions:
CommandOutputUse Case
/code```\n\n```Insert fenced code block
/tableMarkdown table templateCreate a table structure
/todo- [ ] Start a task list
/divider---Insert horizontal rule
Using slash commands:
  1. Type / in the editor
  2. See available commands
  3. Type command name or use arrow keys
  4. Press Enter to insert
  5. Cursor automatically positions for editing
Global keyboard navigation is planned but not yet implemented.
Current navigation:
  • Use Tab to move between UI elements
  • Use arrow keys in suggestions and menus
  • Use Enter to confirm selections
  • Use Esc to close dialogs and menus

API Usage

Create Shortcut

import { createPromiseClient } from "@connectrpc/connect";
import { createConnectTransport } from "@connectrpc/connect-web";
import { ShortcutService } from "./gen/api/v1/shortcut_service_pb";

const client = createPromiseClient(ShortcutService, transport);

const shortcut = await client.createShortcut({
  parent: "users/123", // Your user resource name
  shortcut: {
    title: "💼 Work TODOs",
    filter: 'tag_search == "work" && property.has_incomplete_tasks == true',
  },
});

console.log("Created:", shortcut.name);
// Output: "users/123/shortcuts/abc-def-ghi"

List Shortcuts

const response = await client.listShortcuts({
  parent: "users/123",
});

for (const shortcut of response.shortcuts) {
  console.log(`${shortcut.title}: ${shortcut.filter}`);
}

// Output:
// 💼 Work TODOs: tag_search == "work" && property.has_incomplete_tasks == true
// ✅ Completed: property.has_task_list == true && !property.has_incomplete_tasks

Update Shortcut

import { create } from "@bufbuild/protobuf";
import { FieldMaskSchema } from "@bufbuild/protobuf/wkt";

await client.updateShortcut({
  shortcut: {
    name: "users/123/shortcuts/abc-def-ghi",
    title: "🔥 Urgent Work", // Updated title
    filter: 'tag_search == "work" && tag_search == "urgent"', // Updated filter
  },
  updateMask: create(FieldMaskSchema, {
    paths: ["title", "filter"],
  }),
});

Delete Shortcut

await client.deleteShortcut({
  name: "users/123/shortcuts/abc-def-ghi",
});

console.log("Shortcut deleted");

Validate Filter

Test a filter without creating:
try {
  await client.createShortcut({
    parent: "users/123",
    shortcut: {
      title: "Test",
      filter: 'tag_search == "work"',
    },
    validateOnly: true, // Don't actually create
  });
  console.log("✓ Filter is valid");
} catch (error) {
  console.error("✗ Invalid filter:", error.message);
}

Advanced Techniques

Combining Multiple Tags

Create shortcuts for tag combinations:
# Any of multiple tags (OR)
tag_search == "work" || tag_search == "project" || tag_search == "client"

# All tags must match (AND)
# Note: Single memo can't have multiple tag_search values simultaneously
# Use hierarchical tags instead: #work/project/client
tag_search == "work/project/client"

Date-Based Shortcuts

# This quarter (Q1 2024)
create_time >= timestamp("2024-01-01T00:00:00Z") &&
create_time < timestamp("2024-04-01T00:00:00Z")

# This year
create_time >= timestamp("2024-01-01T00:00:00Z")

# Older than 90 days
create_time < timestamp("2023-10-27T00:00:00Z")
Update timestamps periodically, or build a tool to generate dynamic shortcuts.

Complex Workflows

Chain filters for advanced workflows:
# Sprint planning: Incomplete work items not blocked
tag_search.startsWith("sprint/") && 
property.has_incomplete_tasks == true &&
!(tag_search == "blocked")

# Review queue: Public posts with links for review
visibility == "PUBLIC" &&
property.has_link == true &&
tag_search == "review"

# Archive candidates: Old completed tasks
property.has_task_list == true &&
!property.has_incomplete_tasks &&
create_time < timestamp("2023-01-01T00:00:00Z")

Sharing Shortcuts

Shortcuts are per-user but filters are portable:
  1. Export your filter expressions
  2. Share with teammates
  3. They recreate shortcuts with same filters
  4. Team maintains consistent filtering
Team filter library example:
const teamFilters = {
  "Work TODOs": 'tag_search == "work" && property.has_incomplete_tasks == true',
  "Team Updates": 'tag_search == "team" || tag_search == "meeting"',
  "Code Reviews": 'tag_search == "code-review" && property.has_link == true',
};

// Create for current user
for (const [title, filter] of Object.entries(teamFilters)) {
  await client.createShortcut({
    parent: currentUser.name,
    shortcut: { title, filter },
  });
}

Best Practices

  • Use emoji for visual scanning
  • Keep titles under 20 characters
  • Use action words: “Review”, “Update”, “Check”
  • Group related shortcuts with emoji families
Good:
  • ✅ Complete Tasks
  • 🔄 In Progress
  • ⏸️ Blocked
Bad:
  • Tasks that are complete
  • WIP Items
  • Stuff I can’t do yet
  • Start simple, refine over time
  • Test filters before saving
  • Document complex logic in memo
  • Use shortcuts for 2+ filter combinations
  • One-off filters don’t need shortcuts
  • Limit to 5-10 shortcuts
  • Delete unused shortcuts
  • Order by frequency of use
  • Group by workflow (work, personal, projects)
  • Review and update quarterly
  • Specific filters are faster than broad ones
  • Use indexed fields (tags, visibility)
  • Avoid expensive operations in filters
  • Test shortcuts with large datasets

Troubleshooting

Symptoms:
  • No memos shown
  • Wrong memos displayed
  • Error message
Solutions:
  1. Validate filter syntax
  2. Check field names (case-sensitive)
  3. Verify timestamps format
  4. Test filter components individually
  5. Review server logs for validation errors
Causes:
  • Invalid filter expression
  • Empty title or filter
  • Network error
  • Permission issue
Solutions:
  • Validate filter first
  • Check browser console
  • Verify authentication
  • Try simpler filter
Symptoms:
  • Slow filter application
  • Timeout errors
  • UI lag
Solutions:
  • Simplify filter logic
  • Add more specific conditions
  • Use tag filters instead of content search
  • Paginate results
  • Check database indexes

Tips & Tricks

Quick Tags

Create shortcuts for your most-used tags to avoid typing:
tag_search == "meeting"
tag_search == "work"
tag_search == "personal"

Smart Archives

Find old completed items for archiving:
!property.has_incomplete_tasks &&
create_time < timestamp("2023-01-01T00:00:00Z")

Review Queue

Items needing review:
tag_search == "review" ||
(tag_search == "draft" && visibility == "PRIVATE")

Today's Focus

High-priority incomplete tasks:
(tag_search == "urgent" || pinned == true) &&
property.has_incomplete_tasks == true

Next Steps

Tags & Filters

Learn CEL filter syntax and advanced filtering

Creating Memos

Master memo creation and organization

API Reference

Full shortcut API documentation

Productivity Guide

Workflows and productivity tips

Build docs developers (and LLMs) love