app.clipboard - 剪贴板 API

读写系统剪贴板。

方法

app.clipboard.getText()

获取剪贴板文本内容。

返回值: string|nil - 文本内容或 nil

local text = app.clipboard.getText()
if text then
    app.log.info("剪贴板内容: " .. text)
end

app.clipboard.setText(text)

设置剪贴板文本内容。

参数:

  • text (string) - 要复制的文本

返回值: boolean - 是否成功

app.clipboard.setText("复制的内容")

app.clipboard.getFiles()

获取剪贴板中的文件路径。

返回值: table|nil - 文件路径数组或 nil

local files = app.clipboard.getFiles()
if files then
    for _, file in ipairs(files) do
        app.log.info("文件: " .. file)
    end
end

app.clipboard.setFiles(paths)

设置剪贴板中的文件(复制文件)。

参数:

  • paths (table) - 文件路径数组

返回值: boolean - 是否成功

app.clipboard.setFiles({
    "/path/to/file1.txt",
    "/path/to/file2.txt"
})

app.clipboard.hasText()

检查剪贴板是否包含文本。

返回值: boolean

if app.clipboard.hasText() then
    local text = app.clipboard.getText()
end

app.clipboard.hasFiles()

检查剪贴板是否包含文件。

返回值: boolean

if app.clipboard.hasFiles() then
    local files = app.clipboard.getFiles()
end

app.clipboard.clear()

清空剪贴板。

返回值: boolean - 是否成功

app.clipboard.clear()

app.clipboard.getImage(savePath)

将剪贴板中的图片保存到文件。

参数:

  • savePath (string) - 保存路径

返回值: boolean, error

local ok, err = app.clipboard.getImage("/tmp/clipboard_image.png")
if ok then
    app.log.info("图片已保存")
end

app.clipboard.setImage(imagePath)

将图片文件设置到剪贴板。

参数:

  • imagePath (string) - 图片文件路径

返回值: boolean, error

local ok, err = app.clipboard.setImage("/path/to/image.png")

app.clipboard.hasImage()

检查剪贴板是否包含图片。

返回值: boolean

if app.clipboard.hasImage() then
    app.clipboard.getImage("/tmp/clipboard.png")
end

app.clipboard.getTypes()

获取剪贴板中可用的数据类型列表。

返回值: array<string>, error - UTI 类型字符串数组

local types, err = app.clipboard.getTypes()
if types then
    for _, t in ipairs(types) do
        app.log.info("类型: " .. t)
    end
end

app.clipboard.getHTML()

获取剪贴板中的 HTML 内容。

返回值: string|nil - HTML 内容或 nil

local html = app.clipboard.getHTML()
if html then
    app.log.info("HTML 长度: " .. #html)
end

app.clipboard.setHTML(html)

设置剪贴板 HTML 内容。

参数:

  • html (string) - HTML 内容

返回值: boolean, error

app.clipboard.setHTML("<b>加粗文本</b>")

app.clipboard.getRTF()

获取剪贴板中的 RTF 内容。

返回值: string|nil - RTF 内容或 nil

local rtf = app.clipboard.getRTF()

app.clipboard.setRTF(rtf)

设置剪贴板 RTF 内容。

参数:

  • rtf (string) - RTF 内容

返回值: boolean, error

app.clipboard.setRTF(rtfContent)

app.clipboard.writeMultiple(items)

同时写入多种格式到剪贴板。

参数:

  • items (array) - 项目数组,每项为 {type, data}:
    • type (string) - 类型: "text", "html", "rtf", "files", "image"
    • data (any) - 数据内容

返回值: boolean, error

app.clipboard.writeMultiple({
    {type = "text", data = "纯文本"},
    {type = "html", data = "<b>HTML 版本</b>"}
})

app.clipboard.getContents()

一次性获取剪贴板所有格式内容。

返回值: table - 包含以下可选字段:

  • text (string) - 文本内容
  • html (string) - HTML 内容
  • rtf (string) - RTF 内容
  • files (array) - 文件路径
  • hasImage (boolean) - 是否含有图片
local contents = app.clipboard.getContents()
if contents.text then
    app.log.info("文本: " .. contents.text)
end
if contents.html then
    app.log.info("HTML: " .. contents.html)
end
if contents.files then
    app.log.info("文件数: " .. #contents.files)
end

示例

复制文件路径

function MyPlugin:handleCopyPath(context)
    local paths = {}
    for _, file in ipairs(context.selectedFiles) do
        table.insert(paths, file)
    end

    local text = table.concat(paths, "\n")
    app.clipboard.setText(text)

    app.notification.show("已复制", #paths .. " 个路径已复制到剪贴板")
end

复制文件名列表

function MyPlugin:handleCopyNames(context)
    local names = {}
    for _, file in ipairs(context.selectedFiles) do
        table.insert(names, app.path.basename(file))
    end

    app.clipboard.setText(table.concat(names, "\n"))
    app.notification.show("已复制", #names .. " 个文件名")
end

从剪贴板粘贴文件

function MyPlugin:handlePasteFiles(context)
    local dir = context.currentDirectory

    if app.clipboard.hasFiles() then
        local files = app.clipboard.getFiles()
        for _, src in ipairs(files) do
            local name = app.path.basename(src)
            local dest = app.path.join(dir, name)
            app.file.copy(src, dest)
        end
        app.notification.show("完成", "已粘贴 " .. #files .. " 个文件")
    else
        app.dialog.alert("提示", "剪贴板中没有文件")
    end
end

复制为 Markdown 链接

function MyPlugin:handleCopyAsMarkdown(context)
    local links = {}
    for _, file in ipairs(context.selectedFiles) do
        local name = app.path.basename(file)
        table.insert(links, string.format("[%s](%s)", name, file))
    end

    app.clipboard.setText(table.concat(links, "\n"))
    app.notification.show("已复制", "Markdown 链接已复制")
end

app.clipboard.observe - 剪贴板监听 API

监听系统剪贴板变化事件。

注意: 此模块用于监听变化事件,读写剪贴板内容请使用 app.clipboard

方法

app.clipboard.watch(callback)

注册剪贴板变化监听器。当剪贴板内容发生变化时,回调函数被调用。

参数:

  • callback (function) - 回调函数,接收 event 参数:
    • event.changeCount (number) - 变化计数
    • event.types (array) - 当前剪贴板包含的类型列表
    • event.hasText (boolean) - 是否包含文本
    • event.hasFiles (boolean) - 是否包含文件
    • event.hasImage (boolean) - 是否包含图片

返回值: string, error - 监听器 ID

local id, err = app.clipboard.watch(function(event)
    app.log.info("剪贴板变化: " .. event.changeCount)
    if event.hasText then
        local text = app.clipboard.getText()
        app.log.info("新文本: " .. (text or ""))
    end
    if event.hasFiles then
        app.log.info("包含文件")
    end
end)

app.clipboard.unwatch(id)

移除指定的剪贴板监听器。

参数:

  • id (string) - 监听器 ID

返回值: boolean, error

local ok, err = app.clipboard.unwatch(id)

app.clipboard.unwatchAll()

移除当前插件的所有剪贴板监听器。

返回值: boolean

app.clipboard.unwatchAll()

app.clipboard.list()

列出当前插件的活跃监听器。

返回值: array<table> - 每项包含:

  • id (string) - 监听器 ID
local watchers = app.clipboard.list()
for _, w in ipairs(watchers) do
    app.log.info("Watcher: " .. w.id)
end

说明

  • 每个插件最多 5 个监听器
  • 使用 0.5 秒间隔轮询检测变化(非实时)
  • 回调仅通知变化事件,不包含实际内容(需调用 app.clipboard.getText() 等获取)
  • 监听器在插件卸载时自动移除
  • 回调在插件执行队列上调用(线程安全)

示例

剪贴板历史记录

local history = {}
local MAX_HISTORY = 20

function MyPlugin:init()
    app.clipboard.watch(function(event)
        if event.hasText then
            local text = app.clipboard.getText()
            if text and text ~= "" then
                table.insert(history, 1, {
                    text = text,
                    time = os.date("%H:%M:%S")
                })
                if #history > MAX_HISTORY then
                    table.remove(history)
                end
                app.log.debug("剪贴板历史: " .. #history .. " 条")
            end
        end
    end)
end
开发者文档
使用帮助
使用说明 脚本菜单 常见问题
脚本开发
开发指南
插件开发
快速开始 开发指南 示例插件
API 参考
概览 API 查询 插件信息 日志 Finder 上下文 插件设置 国际化
UI 与交互
对话框 进度条 系统通知 选择器 WebView 状态栏 Dock
文件与路径
文件操作 路径工具 Finder 操作 废纸篓 扩展属性 元数据 文件监听
数据格式
JSON Plist CSV XML PDF 图片
文本与编码
字符串 正则表达式 日期时间 颜色 加密编码
系统
Shell 命令 进程管理 应用管理 系统信息 AppleScript 快捷指令
系统信息
网络信息 电源/电池 屏幕/外观 音频控制 蓝牙设备 位置服务
网络
HTTP 请求 WebSocket URL 工具
输入与剪贴板
键盘模拟 鼠标模拟 全局热键 剪贴板 窗口管理
存储
SQLite Keychain UserDefaults
媒体
文字识别 二维码
工具
归档 类型标识 分享 定时器 防休眠 并发/协程