
Cherry Studio 长文本粘贴行为恢复默认内联粘贴与文件转换选项的完整解析【免费下载链接】cherry-studio Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端项目地址: https://gitcode.com/CherryHQ/cherry-studio本篇技术指南聚焦 Cherry Studio v2 重构中「长文本粘贴」行为的一次重要变更对应 breaking-change 记录 2026-08-30-restore-long-text-paste-settings.mdPR #18693新安装默认将长文本直接内联粘贴到聊天输入框同时将「长文本转文件」开关与长度阈值恢复至设置界面。阅读完本文你将掌握该行为的默认值体系、粘贴分流的底层实现paste handler 决策链、v1 升级映射与 v2 兼容性 seed 机制以及如何在设置界面按需恢复旧的文件转换行为。变更概要三类用户的不同默认行为本次变更的核心是调整长文本粘贴的默认策略并针对不同来源的安装分别处理避免升级过程中的行为突变用户类型默认行为说明全新安装v2长文本直接内联粘贴到聊天输入框无需先改设置即可粘贴长文本已有 v2 安装升级保留此前「长文本转文件」的行为通过兼容性 Seeder 注入旧默认值实现v1 升级到 v2保留用户原始设置通过迁移映射Mappings原样迁移用户偏好关键变化点在于新安装的默认值从「长文本转文件」回退为「内联粘贴」即chat.input.paste_long_text_as_file默认为false「长文本转文件」开关及其长度阈值重新在设置 → 消息 → 输入Settings → Messages → Input中可用对已有用户而言升级过程完全自动不需要手动操作若已有用户偏好内联粘贴也可以在输入设置中关闭「长文本转文件」选项。偏好项定义两个关键配置键本次变更涉及的两个偏好项定义在偏好 schema 中位于 preferenceSchemas.ts// redux/settings/pasteLongTextAsFile chat.input.paste_long_text_as_file: boolean // redux/settings/pasteLongTextThreshold chat.input.paste_long_text_threshold: number两个键的默认值在同文件 defaultPreferences 中定义chat.input.paste_long_text_as_file: false, chat.input.paste_long_text_threshold: 1500,偏好键类型默认值含义chat.input.paste_long_text_as_filebooleanfalse是否将超过阈值的长文本粘贴为文件附件chat.input.paste_long_text_thresholdnumber1500触发「长文本转文件」的字符长度阈值字符数从 schema 中的注释// redux/settings/pasteLongTextAsFile可以推断这两个键在 v1 中对应 Redux settings 下的pasteLongTextAsFile与pasteLongTextThresholdv2 统一收敛为带命名空间的chat.input.*偏好键。与阈值相关的常量同时存在于渲染进程的粘贴逻辑中见 composerPaste.tsexport const LONG_TEXT_PASTE_THRESHOLD 1500 export const PASTED_TEXT_FILE_EXTENSION .txtLONG_TEXT_PASTE_THRESHOLD 1500与偏好默认值保持一致作为未显式传入阈值时的兜底常量PASTED_TEXT_FILE_EXTENSION .txt则限定了长文本转文件时生成的临时文件类型。粘贴分流的源码实现长文本何时变成文件长文本转文件的核心决策逻辑位于 pasteHandling.ts 的handlePaste函数中。该函数按优先级依次处理剪贴板内容文本 → 文件/图片 → 默认粘贴。关键分支如下// 1. 文本粘贴仅在用户开启“长文本转文件”时生效 if (pasteLongTextAsFile clipboardText.length (pasteLongTextThreshold ?? LONG_TEXT_PASTE_THRESHOLD)) { if (!supportExts.includes(PASTED_TEXT_FILE_EXTENSION)) return false // 长文本直接转文件阻止默认粘贴 event.preventDefault() const tempFilePath await window.api.file.createTempFile(pasted_text.txt) await window.api.file.write(tempFilePath, clipboardText) const selectedFile await window.api.file.get(tempFilePath) if (selectedFile) { const pastedTextFile: PastedTextFileMetadata { ...selectedFile, origin_name: t?.(chat.input.pasted_text_file_name) ?? selectedFile.origin_name, composerFileKind: COMPOSER_FILE_KIND.PASTED_TEXT } setFiles((prevFiles) [...prevFiles, toComposerAttachment(pastedTextFile)]) if (setText text) setText(text) // 保持输入框内容不变 if (resizeTextArea) setTimeout(() resizeTextArea(), 50) } return true } // 短文本走默认粘贴行为直接返回 return false对照 pasteHandling.ts 源码可以梳理出完整的执行链路条件判断pasteLongTextAsFile必须为true且剪贴板文本长度严格大于阈值不含等于此时才进入文件转换分支否则直接返回false交由编辑器执行默认的内联粘贴扩展名校验检查当前会话支持的文件扩展名集合是否包含.txt不包含则放弃转换阻止默认行为调用event.preventDefault()避免文本同时被编辑器内联插入生成临时文件通过window.api.file.createTempFile(pasted_text.txt)创建临时文件并用window.api.file.write(tempFilePath, clipboardText)写入剪贴板文本构造附件读取临时文件信息后包装为PastedTextFileMetadata标记composerFileKind: COMPOSER_FILE_KIND.PASTED_TEXT再通过toComposerAttachment转为ComposerAttachment追加到附件列表保持输入框内容setText(text)确保原文本仍保留在输入框中预览保留并延时触发resizeTextArea自适应高度。从实现看这是一个「渲染进程内联判断 主进程文件 I/O」的协作流程判断与分流在渲染进程完成文件创建与写入经由window.api.file.*桥接到主进程的文件服务。与之配套的是纯文本粘贴覆盖逻辑 getComposerPlainTextPasteOverrideexport function getComposerPlainTextPasteOverride(text: string, options: ComposerPlainTextPasteOptions) { if (!text) return null if (!options.inlineLongText text.length LONG_TEXT_PASTE_THRESHOLD) { return null } const linkContent createComposerLinkPasteContent(text) if (linkContent) return linkContent // ... 链接 token 与 markdown 标记处理 return createComposerPlainTextPasteContent(text) }这里options.inlineLongText与阈值LONG_TEXT_PASTE_THRESHOLD协同当未开启内联长文本即开启了转文件且文本超长时直接返回null放弃对纯文本粘贴的特殊格式化如链接 token 化、Markdown 标记高亮确保长文本能被上层统一拦截并转为文件避免走格式化粘贴路径产生冲突。设置界面开关与阈值如何呈现两个偏好项在设置界面中回归实现在 ChatPreferenceSections.tsxSettingRow classNamescroll-mt-6 SettingSwitch checked{pasteLongTextAsFile} onCheckedChange{setPasteLongTextAsFile} label{t(settings.messages.input.paste_long_text_as_file)} / /SettingRow {pasteLongTextAsFile ( SettingDivider / SettingRow SettingRowTitleSmall{t(settings.messages.input.paste_long_text_threshold)}/SettingRowTitleSmall InputNumber sizesmall classNamew-20 text-sm aria-label{t(settings.messages.input.paste_long_text_threshold)} min{500} max{10000} step{100} value{pasteLongTextThreshold} onBlur{(value) setPasteLongTextThreshold(value ?? 500)} / /SettingRow / )}界面交互要点开关pasteLongTextAsFile为false时默认状态阈值输入框不渲染界面保持简洁阈值输入框仅在开关开启后出现为数字输入组件约束为min 500、max 10000、step 100即阈值允许范围是 50010000 字符步进 100失焦兜底onBlur时若输入为空自动回退为500保证值合法文案由 i18n 提供英文环境对应 Paste long text as file 与 Paste long text length见 en-us.json中文等多语言环境均有对应翻译分布在 zh-cn.json 等各语言文件中。对已有用户而言若偏好内联粘贴只需在设置 → 消息 → 输入中关闭「长文本转文件」开关新安装用户则无需任何操作默认即为内联粘贴。升级兼容性v1 映射与 v2 Seeder 如何协同本次变更对「已有用户不产生意外行为变化」的承诺由两条独立的机制共同保障v1 → v2 迁移映射保留用户原始设置v1 用户升级时其 Redux settings 中的原始配置通过映射表迁移到 v2 偏好键见 PreferencesMappings.ts{ originalKey: pasteLongTextAsFile, targetKey: chat.input.paste_long_text_as_file }, { originalKey: pasteLongTextThreshold, targetKey: chat.input.paste_long_text_threshold },也就是说v1 中用户手工设置的开关状态与阈值会原样保留不会被新默认值覆盖。对应测试 PreferencesMigrator.test.ts 验证了这一点当 v1 上下文中pasteLongTextAsFile: false、pasteLongTextThreshold: 3200时迁移后chat.input.paste_long_text_as_file为false、chat.input.paste_long_text_threshold为3200完全保留用户选择。已有 v2 安装的兼容性 Seeder保留旧的文件转换行为对于已经运行过 v2 的存量安装由于新版本 schema 默认值从true改回了false为避免升级后粘贴行为突变引入了专门的 Seeder —— longTextPastePreferenceUpgradeSeeder.tsconst EXISTING_V2_COMPATIBILITY_DEFAULTS [ { scope: default, key: chat.input.paste_long_text_as_file, value: true }, { scope: default, key: chat.input.paste_long_text_threshold, value: 1500 } ] as const const EXISTING_V2_PREFERENCE_KEY app.language其逻辑是查询scope default且 key 为app.language的偏好是否存在 —— 以此作为「已有 v2 安装」的探针新装数据库不会包含该键若存在说明是存量 v2 数据库则检查chat.input.paste_long_text_as_file与chat.input.paste_long_text_threshold是否已存在仅对缺失的键插入兼容性默认值true/1500false时跳过避免覆盖用户已有选择从而让存量 v2 用户继续沿用「长文本转文件」的旧行为。该 Seeder 的描述为 Preserve long-text file paste behavior for existing v2 installations与 breaking-change 文档的表述完全一致。其配套测试见 longTextPastePreferenceUpgradeSeeder.test.ts。三路径汇总安装来源生效机制结果全新 v2 安装schema 默认值false/1500长文本内联粘贴存量 v2 升级LongTextPastePreferenceUpgradeSeeder注入兼容默认值true/1500保持文件转换行为v1 升级PreferencesMappings迁移映射保留用户原始开关与阈值常见问题排查Q1升级到新版本后长文本仍会被转成文件如何改为内联粘贴这是存量 v2 安装的正常表现——兼容性 Seeder 保留了旧行为。前往设置 → 消息 → 输入关闭「Paste long text as file」长文本转文件开关即可恢复内联粘贴。Q2阈值设置无效确认开关已开启阈值输入框仅在开关开启后显示且粘贴文本长度需严格大于阈值才会触发转换源码使用比较等于阈值不会触发。阈值可设置范围为 50010000步进 100失焦为空时回退为 500。Q3转文件后输入框中的原文被清空了源码在setFiles后调用了setText(text)以保持输入框内容不变若你观察到输入框内容变化可检查当前会话的.txt支持情况——当supportExts不包含.txt时转换分支会直接返回false走默认内联粘贴不会产生文件附件。Q4新装用户为何默认内联粘贴这是本次变更的既定策略breaking-change 记录categorychangedseveritynotice新装默认值chat.input.paste_long_text_as_file false让新用户无需预先调整设置即可直接粘贴长文本同时对存量用户通过 Seeder / 迁移保持行为连续性实现默认变更 升级无损的目标。参考与延伸变更记录原文2026-08-30-restore-long-text-paste-settings.md偏好键与默认值定义preferenceSchemas.ts粘贴处理核心实现pasteHandling.ts常量与纯文本粘贴覆盖composerPaste.ts设置界面实现与测试ChatPreferenceSections.tsx、ChatPreferenceSections.test.tsxv1 迁移映射与测试PreferencesMappings.ts、PreferencesMigrator.test.tsv2 存量兼容 Seeder 与测试longTextPastePreferenceUpgradeSeeder.ts、longTextPastePreferenceUpgradeSeeder.test.ts【免费下载链接】cherry-studio Cherry Studio 是一款支持多个 LLM 提供商的桌面客户端项目地址: https://gitcode.com/CherryHQ/cherry-studio创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考