Skip to content

Improve Cut and Paste - #17850

Merged
88250 merged 4 commits into
siyuan-note:devfrom
zxkmm:cp_paste_ai_0
Jun 17, 2026
Merged

Improve Cut and Paste#17850
88250 merged 4 commits into
siyuan-note:devfrom
zxkmm:cp_paste_ai_0

Conversation

@zxkmm

@zxkmm zxkmm commented Jun 12, 2026

Copy link
Copy Markdown
Member

Description / 描述

as per discussions in #17679

Type of change / 变更类型

  • Bug fix
    缺陷修复
  • Refactoring
    代码重构
  • New feature
    新功能
  • Text updates or new language additions
    修改文案或增加新语言

Checklist / 检查清单

  • I have performed a self-review of my own code
    我对自己的代码进行了自我审查
  • I have full rights to the submitted code and agree to license it under this project's AGPL-3.0 license
    我拥有所提交代码的完整权利,并同意其以本项目的 AGPL-3.0 许可证授权
  • PR is submitted to the dev branch and has no merge conflicts
    PR 提交到 dev 分支,并且没有合并冲突

@zxkmm
zxkmm marked this pull request as ready for review June 13, 2026 05:35
@zxkmm zxkmm changed the title [WIP] New Cut and paste #17679 New Cut and paste #17679 Jun 13, 2026
@TCOTC

TCOTC commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

我还没看代码和测试,仅补充一个场景:

打开文档 A → 剪切一个块 → 关闭文档 A → 打开文档 B → 粘贴块到里面 → 打开文档 A → 在文档 A 里撤销

@zxkmm

zxkmm commented Jun 15, 2026

Copy link
Copy Markdown
Member Author

刚看了一下 你说的这个场景,fable 5 写的代码 确实没有覆盖

@zxkmm
zxkmm marked this pull request as draft June 15, 2026 03:23
@88250

88250 commented Jun 15, 2026

Copy link
Copy Markdown
Member

我还没看代码和测试,仅补充一个场景:

打开文档 A → 剪切一个块 → 关闭文档 A → 打开文档 B → 粘贴块到里面 → 打开文档 A → 在文档 A 里撤销

这个场景思源本身也不支持,关闭 A 后就不支持撤销了。我觉得应该是属于 #4866 的支持范围。

@zxkmm

zxkmm commented Jun 15, 2026

Copy link
Copy Markdown
Member Author

我可以看看等fable可以用了以后,看看fable有没有什么办法实现#4866

@88250

88250 commented Jun 15, 2026

Copy link
Copy Markdown
Member

好,那现在这个应该可以 review 了吧?

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors cut/copy/paste and undo behavior to better preserve block reference integrity by conditionally keeping original block IDs on paste, supported by a new bulk “block IDs exist” kernel API.

Changes:

  • Add kernel API endpoint /api/block/checkBlocksExist to bulk-check whether block IDs exist.
  • Update editor paste logic to keep original block IDs when they no longer exist (cut→paste), and regenerate IDs only when they still exist (copy→paste).
  • Add an undo-time duplicate-ID resolver to avoid inserting blocks with IDs already present after cross-editor cut/paste.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
kernel/api/router.go Registers the new bulk block existence API route.
kernel/api/block.go Implements checkBlocksExist handler and validation/filtering of IDs.
app/src/protyle/util/paste.ts Uses bulk existence check to decide whether to keep or regenerate pasted block IDs.
app/src/protyle/undo/index.ts Adds duplicate-ID resolution before replaying insert operations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread kernel/api/block.go
Comment on lines +395 to +402
idsArg := arg["ids"].([]interface{})
var ids []string
for _, idArg := range idsArg {
if id, idOk := idArg.(string); idOk && ast.IsNodeIDPattern(id) {
ids = append(ids, id)
}
}
ret.Data = treenode.ExistBlockTrees(ids)
Comment on lines +465 to +475
const oldIds: string[] = [];
pastedBlockElements.forEach((e) => {
oldIds.push(e.getAttribute("data-node-id"));
});
const existResponse = await fetchSyncPost("/api/block/checkBlocksExist", {ids: oldIds});
pastedBlockElements.forEach((e) => {
if (existResponse.data[e.getAttribute("data-node-id")] !== false) {
e.setAttribute("data-node-id", Lute.NewNodeID());
}
clearBlockElement(e);
});
Comment on lines +130 to 134
private async render(protyle: IProtyle, state: IOperations, redo: boolean) {
hideElements(["hint", "gutter"], protyle);
protyle.wysiwyg.lastHTMLs = {};
await this.resolveDuplicateIds(redo ? state.doOperations : state.undoOperations);
if (!redo) {
@zxkmm

zxkmm commented Jun 16, 2026

Copy link
Copy Markdown
Member Author

好,那现在这个应该可以 review 了吧?

我的想法是这个PR供各位参考,不一定要合并,因为这个代码完全是AI生成的,一般大项目我不敢在没有100%把握的情况下用ai代码。当然如果你们感觉没啥问题的话我也可以跟进一下,或者你们push变更到这个pr也行。

@88250

88250 commented Jun 17, 2026

Copy link
Copy Markdown
Member

把草稿状态改成准备合并吧

@zxkmm
zxkmm marked this pull request as ready for review June 17, 2026 01:49
@zxkmm

zxkmm commented Jun 17, 2026

Copy link
Copy Markdown
Member Author

改了

@88250

88250 commented Jun 17, 2026

Copy link
Copy Markdown
Member

我和 V 先把全局撤销解决掉 #4866 就来处理这个,多谢。

@zxkmm

zxkmm commented Jun 17, 2026

Copy link
Copy Markdown
Member Author

不急,我今天再测一下

@88250

88250 commented Jun 17, 2026

Copy link
Copy Markdown
Member

等跨编辑器撤销搞定了再测

@zxkmm

zxkmm commented Jun 17, 2026

Copy link
Copy Markdown
Member Author

嗷~

@88250 88250 changed the title New Cut and paste #17679 Improve Cut and Paste Jun 17, 2026
@88250 88250 assigned 88250 and zxkmm Jun 17, 2026
@88250 88250 added this to the 3.7.0 milestone Jun 17, 2026
@88250

88250 commented Jun 17, 2026

Copy link
Copy Markdown
Member

我们先合并吧,后续修改我这边来搞,多谢。

@zxkmm

zxkmm commented Jun 17, 2026

Copy link
Copy Markdown
Member Author

嗷~我刚好在合并冲突

@88250
88250 merged commit 57819eb into siyuan-note:dev Jun 17, 2026
@zxkmm
zxkmm deleted the cp_paste_ai_0 branch June 17, 2026 12:46
88250 added a commit that referenced this pull request Jun 17, 2026
Signed-off-by: Daniel <845765@qq.com>
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Jul 18, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants