Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Merging changes occuring to the filesystem #19

Open
situ2001 opened this issue Aug 27, 2022 · 3 comments
Open

[Feature] Merging changes occuring to the filesystem #19

situ2001 opened this issue Aug 27, 2022 · 3 comments
Labels
enhancement New feature or request

Comments

@situ2001
Copy link
Owner

situ2001 commented Aug 27, 2022

Tl; DR 把Node也当成协作者就行了。

直到快结束的时候才想到一个问题:当前的假想是用户会直接使用IDE的编辑器对文件进行编辑,而没有考虑到文件在文件系统发生的改变(比如git merge有可能会改变文件)。

如果是以CRDT为中心(在此情景下,在磁盘上的文本文件的作用,仅仅是保存文本)的话,不妨可以假设:文件在文件系统出现了改变,可以等价为用户在编辑器编辑产生的改变(yjs Delta,查阅文档得知格式),用户的输入最终会变为一个一个的Delta,作为Yjs的CRDT的changes。

那么,为什么不把文件系统发生的改变也给归进来呢?关键就是,如果文件在文件系统中的改变,也可以转化为yjs能认的Delta就好了。

这里的想法是将文本文件发生的改变给通过jsdiff得出diff,然后转换到yjs的Delta format,最后merge到Y.Text中,使用ytext.applyDelta(delta: Delta)

那么,crux如下:

  1. 如何得知文件的改变不是用户在IDE的编辑器里编辑而产生的?
  2. 如何将文件在文件系统中发生的变化使用diff处理后apply到Y.Text中?
@situ2001 situ2001 added the enhancement New feature or request label Aug 27, 2022
@situ2001
Copy link
Owner Author

并且,IDE前端有不少更新TextModel的情况,如果有n个client,那么就会出现n份更新...

@situ2001
Copy link
Owner Author

situ2001 commented Aug 28, 2022

并且,IDE前端有不少更新TextModel的情况,如果有n个client,那么就会出现n份更新...

举个例子,比如:监听到文件系统的外部更新,每一个client都会调用一次这个方法。

@OnEvent(EditorDocumentModelOptionExternalUpdatedEvent)
async acceptExternalChange(e: EditorDocumentModelOptionExternalUpdatedEvent) {
if (!this.hashCalculateService.initialized) {
await this.hashCalculateService.initialize();
}
const doc = this.editorDocModels.get(e.payload.toString());
if (doc) {
if (doc.dirty) {
// do nothing
} else {
const provider = await this.contentRegistry.getProvider(doc.uri);
if (provider) {
if (provider.provideEditorDocumentModelContentMd5) {
const nextMd5 = await provider.provideEditorDocumentModelContentMd5(doc.uri, doc.encoding);
if (nextMd5 !== doc.getBaseContentMd5()) {
doc.updateContent(await this.contentRegistry.getContentForUri(doc.uri, doc.encoding), undefined, true);
}
} else {
const content = await this.contentRegistry.getContentForUri(doc.uri, doc.encoding);
if (this.hashCalculateService.calculate(content) !== doc.getBaseContentMd5()) {
doc.updateContent(content, undefined, true);
}
}
}
}
}
}

@situ2001
Copy link
Owner Author

situ2001 commented Aug 28, 2022

不过,对于上述问题,专门为协同状态下的IDE实现IEditorDocumentModelContentProvider就行了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant