11import { Autowired } from '@ali/common-di' ;
22import { ClientAppContribution } from '@ali/ide-core-browser' ;
3- import { OnEvent , WithEventBus , BasicEvent , Domain } from '@ali/ide-core-common' ;
3+ import { OnEvent , WithEventBus , BasicEvent , Domain , URI } from '@ali/ide-core-common' ;
44import {
55 EditorDocumentModelSavedEvent ,
66 EditorDocumentModelContentChangedEvent ,
77 IEditorDocumentModelService ,
88} from '@ali/ide-editor/lib/browser' ;
9- import { IFileServiceClient } from '@ali/ide-file-service/lib/common' ;
9+ import { IFileServiceClient , FileChangeType } from '@ali/ide-file-service/lib/common' ;
1010import { AppConfig , RuntimeConfig } from '../../common/types' ;
1111import * as path from 'path' ;
1212
@@ -31,12 +31,78 @@ export class EditorActionEventContribution extends WithEventBus implements Clien
3131
3232 onStart ( ) { }
3333
34+ initialize ( ) {
35+ type EventType = { uri : string ; filepath : string } ;
36+
37+ this . addDispose (
38+ this . fileService . onFilesChanged ( ( changes ) => {
39+ const created : EventType [ ] = [ ] ;
40+ const changed : EventType [ ] = [ ] ;
41+ const deleted : EventType [ ] = [ ] ;
42+
43+ for ( const change of changes ) {
44+ const relativePath = this . getWorkspaceRelativePath ( new URI ( change . uri ) ) ;
45+ if ( relativePath === null ) {
46+ continue ;
47+ }
48+ const obj : EventType = { uri : change . uri , filepath : relativePath } ;
49+ switch ( change . type ) {
50+ case FileChangeType . ADDED :
51+ created . push ( obj ) ;
52+ break ;
53+ case FileChangeType . UPDATED :
54+ changed . push ( obj ) ;
55+ break ;
56+ case FileChangeType . DELETED :
57+ deleted . push ( obj ) ;
58+ break ;
59+ default :
60+ break ;
61+ }
62+ }
63+
64+ const { workspace } = this . runtimeConfig ;
65+ if ( created . length && workspace ?. onDidCreateFiles ) {
66+ workspace . onDidCreateFiles ( created . map ( ( data ) => data . filepath ) ) ;
67+ }
68+ if ( deleted . length && workspace ?. onDidDeleteFiles ) {
69+ workspace . onDidDeleteFiles ( deleted . map ( ( data ) => data . filepath ) ) ;
70+ }
71+ if ( changed . length && workspace ?. onDidChangeFiles ) {
72+ const { onDidChangeFiles } = workspace ;
73+ // TODO: 直接返回 buffer? 编码假定为 utf8 了
74+ Promise . all (
75+ changed . map ( async ( { uri, filepath } ) => {
76+ const { content } = await this . fileService . resolveContent ( uri ) ;
77+ return {
78+ filepath,
79+ content,
80+ } ;
81+ } )
82+ )
83+ . then ( ( data ) => {
84+ onDidChangeFiles ( data ) ;
85+ } )
86+ . catch ( ( err ) => {
87+ console . error ( err ) ;
88+ } ) ;
89+ }
90+ } )
91+ ) ;
92+ }
93+
3494 @OnEvent ( EditorDocumentModelSavedEvent )
3595 async onEditorDocumentModelSavingEvent ( e : EditorDocumentModelSavedEvent ) {
3696 if ( this . runtimeConfig . workspace ?. onDidSaveTextDocument ) {
3797 const uri = e . payload ;
98+ if ( uri . scheme !== 'file' ) {
99+ return ;
100+ }
38101 const { content } = await this . fileService . resolveContent ( uri . toString ( true ) ) ;
39- const filepath = path . relative ( this . appConfig . workspaceDir , uri . codeUri . fsPath ) ;
102+ const filepath = this . getWorkspaceRelativePath ( uri ) ;
103+ if ( filepath === null ) {
104+ return ;
105+ }
40106 this . runtimeConfig . workspace . onDidSaveTextDocument ( { filepath, content } ) ;
41107 }
42108 }
@@ -45,14 +111,30 @@ export class EditorActionEventContribution extends WithEventBus implements Clien
45111 async onEditorDocumentModelContentChangedEvent ( e : EditorDocumentModelContentChangedEvent ) {
46112 if ( this . runtimeConfig . workspace ?. onDidChangeTextDocument ) {
47113 const { uri } = e . payload ;
114+ if ( uri . scheme !== 'file' ) {
115+ return ;
116+ }
48117 const model = this . docModelService . getModelReference ( uri ) ;
49118 if ( model ) {
50- const filepath = path . relative ( this . appConfig . workspaceDir , uri . codeUri . fsPath ) ;
119+ const filepath = this . getWorkspaceRelativePath ( uri ) ;
120+ if ( filepath === null ) {
121+ return ;
122+ }
51123 this . runtimeConfig . workspace . onDidChangeTextDocument ( {
52124 filepath,
53125 content : model . instance . getText ( ) ,
54126 } ) ;
127+ model . dispose ( ) ;
55128 }
56129 }
57130 }
131+
132+ getWorkspaceRelativePath ( uri : URI ) : string | null {
133+ const absolutePath = uri . codeUri . path ;
134+ const { workspaceDir } = this . appConfig ;
135+ if ( ! absolutePath . startsWith ( workspaceDir ) ) {
136+ return null ;
137+ }
138+ return path . relative ( this . appConfig . workspaceDir , absolutePath ) ;
139+ }
58140}
0 commit comments