fix(editor): 右键粘贴含 CRLF 的剪贴板文本不再报选区越界 (#9576)

SQL 编辑器里选中一百多行后,右键“粘贴”从 Excel 复制的表格数据会报
“读取剪贴板失败:Selection points outside of document”,文档内容不变;
先删除文本再粘贴则正常。

右键粘贴按剪贴板原文长度计算光标位置,而 CodeMirror 会把插入文本中的
\r\n、\r 归一化为 \n,实际写入的文本比原文短,光标落到文档末尾之后,
dispatch 抛出 RangeError: Selection points outside of document。

- 新增 queryEditorClipboardPasteChange:先归一行尾再按实际插入长度计算光标
- QueryEditor 右键粘贴改用它,选区长度不再影响粘贴是否成功

Co-authored-by: zipg <4047349+zipg@users.noreply.github.com>
This commit is contained in:
zipgandzipg authored and GitHub committed 2026-09-19 13:31:40 +08:00
1 parent 58fd050a28
commit ed1881e323
5 files changed
+70 -2

No files matched your search

@@ -182,6 +182,7 @@ import { createDbxCodeMirrorSqlDialect, type CodeMirrorSqlDialectName } from "@/
import { sqlSemanticTableNameSpansForSyntaxTree } from "@/lib/editor/codemirrorSqlSemanticHighlight";
import { startsQueryEditorRectangularSelection, startsQueryEditorSelectionDrag, usesQueryEditorObjectNavigationModifier } from "@/lib/editor/queryEditorPointerSelection";
import { LARGE_PASTE_HISTORY_USER_EVENT, normalizeQueryEditorPasteText, recoverableNativePasteSuffix, shouldRecoverLargeTauriPaste } from "@/lib/editor/queryEditorLargePaste";
import { queryEditorClipboardPasteChange } from "@/lib/editor/queryEditorClipboardPaste";
import { computePasteCaretResyncTarget } from "@/lib/editor/queryEditorPasteCaretResync";
import { queryEditorCommentTokens, queryEditorLineCommentToken, queryEditorWordLanguageData } from "@/lib/editor/queryEditorLineComment";
import { createShellLineCommentHighlight } from "@/lib/editor/codemirrorShellLineCommentHighlight";
@@ -1910,8 +1911,7 @@ async function pasteClipboardSqlFromContextMenu() {
const selection = currentView.state.selection.main;
// 粘贴:替换选中内容或在光标处插入
currentView.dispatch({
changes: { from: selection.from, to: selection.to, insert: text },
selection: { anchor: selection.from + text.length, head: selection.from + text.length },
...queryEditorClipboardPasteChange(text, selection.from, selection.to),
scrollIntoView: true,
userEvent: "input.paste",
});