app.chooser - Quick Chooser API

Provides a Raycast/Alfred-style quick selection interface with search filtering.

Permission: Requires chooser declared in the manifest (L1 standard)

Methods

app.chooser.show(items, options?)

Displays a quick chooser window.

Parameters:

  • items (array) - Option list, each item is a table:
    • text (string) - Primary text (required)
    • subText (string, optional) - Secondary text/description
    • icon (string, optional) - Icon (use sf:symbol.name format for SF Symbols)
    • id (string|number, optional) - Unique identifier
  • options (table, optional):
    • title (string, optional) - Window title
    • placeholder (string, optional) - Search field placeholder
    • multiSelect (boolean, optional) - Enable multi-select (default false)
    • width (number, optional) - Window width (default 500)
    • maxVisibleItems (number, optional) - Maximum visible items (default 10)

Returns:

  • Single-select: The selected item table, or nil (cancelled)
  • Multi-select: Array of selected items, or nil (cancelled)
-- Basic usage
local selected = app.chooser.show({
    {text = "New File",        subText = "Create a blank file",     icon = "sf:doc.badge.plus"},
    {text = "New Folder",      subText = "Create an empty folder",  icon = "sf:folder.badge.plus"},
    {text = "From Template",   subText = "Use a predefined template", icon = "sf:doc.on.doc"},
}, {
    title = "Quick Actions",
    placeholder = "Search actions..."
})

if selected then
    app.log.info("Selected: " .. selected.text)
end

Comparison with dialog.choose

Feature app.chooser.show app.dialog.choose
UI style Standalone floating window + search box NSAlert dropdown/checkbox list
Search filtering Supports real-time search Not supported
Secondary text Supports subText Not supported
Icons Supports SF Symbols Not supported
Use case Quick filtering from many options Simple selection from few options

Examples

Quick open project

function MyPlugin:handleQuickOpen(context)
    -- Build project list
    local items = {}
    local projects = app.file.find("~/Projects", {type = "directory", maxDepth = 1})

    for _, path in ipairs(projects) do
        table.insert(items, {
            id = path,
            text = app.path.basename(path),
            subText = path,
            icon = "sf:folder.fill"
        })
    end

    local selected = app.chooser.show(items, {
        title = "Open Project",
        placeholder = "Search projects..."
    })

    if selected then
        app.shell.execute("open " .. app.shell.quote(selected.id))
    end
end

Command palette

function MyPlugin:handleCommandPalette(context)
    local commands = {
        {id = "copy_path",   text = "Copy Path",       subText = "Copy full file path",     icon = "sf:doc.on.clipboard"},
        {id = "copy_name",   text = "Copy File Name",   subText = "Copy file name",          icon = "sf:textformat"},
        {id = "open_term",   text = "Open in Terminal", subText = "Open Terminal",           icon = "sf:terminal"},
        {id = "compress",    text = "Compress File",    subText = "Create ZIP archive",      icon = "sf:archivebox"},
        {id = "hash",        text = "Calculate Hash",   subText = "SHA256 checksum",         icon = "sf:number"},
    }

    local selected = app.chooser.show(commands, {
        placeholder = "Enter command..."
    })

    if selected then
        self:executeCommand(selected.id, context)
    end
end

Multi-select operation

function MyPlugin:handleSelectTags(context)
    local tags = {
        {id = "important", text = "Important",    icon = "sf:star.fill"},
        {id = "urgent",    text = "Urgent",        icon = "sf:exclamationmark.triangle"},
        {id = "review",    text = "Pending Review", icon = "sf:eye"},
        {id = "archive",   text = "Archive",       icon = "sf:archivebox"},
    }

    local selected = app.chooser.show(tags, {
        title = "Select Tags",
        placeholder = "Search tags...",
        multiSelect = true
    })

    if selected then
        for _, tag in ipairs(selected) do
            app.log.info("Selected tag: " .. tag.text)
        end
    end
end

Notes

  1. Search filtering: Automatically matches against text and subText fields
  2. Blocking call: Blocks the current thread until the user selects or cancels
  3. Icon format: Use the sf: prefix to load SF Symbols (e.g. sf:folder.fill)
Developer Documentation
User Guide
Getting Started Script Menus FAQ
Script Development
Development Guide
Plugin Development
Quick Start Development Guide Example Plugins
API Reference
Overview API Query Plugin Info Logging Finder Context Plugin Settings Internationalization
UI & Interaction
Dialog Progress Notification Chooser WebView Status Bar Dock
Files & Paths
File Operations Path Utilities Finder Actions Trash Extended Attributes Metadata File Watcher
Data Formats
JSON Plist CSV XML PDF Image
Text & Encoding
String Regex Date & Time Color Crypto
System
Shell Commands Process Application System Info AppleScript Shortcuts
System Info
Network Power/Battery Screen/Appearance Audio Bluetooth Location
Network
HTTP WebSocket URL
Input & Clipboard
Keyboard Mouse Hotkey Clipboard Window
Storage
SQLite Keychain UserDefaults
Media
OCR QR Code
Utilities
Archive UTI Share Timer Wake Lock Thread