11import type { WatcherNotificationFileData } from '../../../shared/notificationChannels' ;
2+ import { debug , sanitizeFilePath } from '../notificationReceivers/debug' ;
23import { watcherNotification } from '../lib/notificationChannels' ;
34import type { LanguageClient } from 'vscode-languageclient/node' ;
45import { getEditorConfiguration } from '../lib/editorConfig' ;
56import type { Disposable } from 'vscode' ;
7+ import { createHash } from 'crypto' ;
8+ import * as fs from 'fs/promises' ;
69import * as vscode from 'vscode' ;
7-
810type PartialDocument = Pick <
911 vscode . TextDocument ,
1012 'uri' | 'getText' | 'isDirty' | 'languageId'
@@ -54,11 +56,18 @@ export class DocumentManager implements Disposable {
5456
5557 private async _onDocumentChange ( e : vscode . TextDocument ) : Promise < void > {
5658 if ( this . _isConfigFile ( e ) ) {
59+ debug ( 'configChange' , {
60+ filePath : sanitizeFilePath ( e . uri . fsPath ) ,
61+ } ) ;
5762 await this . _client . sendNotification ( watcherNotification , {
5863 operation : 'onConfigChange' ,
5964 } ) ;
6065 }
6166 if ( this . _shouldSyncDocument ( e ) ) {
67+ debug ( 'documentChange' , {
68+ checking : true ,
69+ filePath : sanitizeFilePath ( e . uri . fsPath ) ,
70+ } ) ;
6271 await this . _client . sendNotification ( watcherNotification , {
6372 operation : 'change' ,
6473 file : this . _toSendData ( e ) ,
@@ -67,16 +76,40 @@ export class DocumentManager implements Disposable {
6776 }
6877
6978 private async _onDocumentSave ( e : vscode . TextDocument ) : Promise < void > {
70- if ( this . _shouldSyncDocument ( e ) ) {
79+ const fileContents = e . getText ( ) ;
80+ const fileContentsHash = createHash ( 'sha256' )
81+ . update ( fileContents )
82+ . digest ( 'hex' ) ;
83+ const onDiskContents = await fs . readFile ( e . uri . fsPath , 'utf-8' ) ;
84+ const onDiskContentsHash = createHash ( 'sha256' )
85+ . update ( onDiskContents )
86+ . digest ( 'hex' ) ;
87+ if ( fileContentsHash !== onDiskContentsHash ) {
88+ debug ( 'documentSave' , {
89+ filePath : sanitizeFilePath ( e . uri . fsPath ) ,
90+ } ) ;
7191 await this . _client . sendNotification ( watcherNotification , {
7292 operation : 'save' ,
7393 file : this . _toSendData ( e ) ,
7494 } ) ;
95+ const postSaveContents = await fs . readFile ( e . uri . fsPath , 'utf-8' ) ;
96+ const postSaveContentsHash = createHash ( 'sha256' )
97+ . update ( postSaveContents )
98+ . digest ( 'hex' ) ;
99+ debug ( 'documentSave' , {
100+ filePath : sanitizeFilePath ( e . uri . fsPath ) ,
101+ postSaveContentsHash,
102+ fileContentsHash,
103+ onDiskContentsHash,
104+ } ) ;
75105 }
76106 }
77107
78108 private async _onDocumentActive ( e : vscode . TextDocument ) : Promise < void > {
79109 if ( this . _shouldSyncDocument ( e ) ) {
110+ debug ( 'documentActive' , {
111+ filePath : sanitizeFilePath ( e . uri . fsPath ) ,
112+ } ) ;
80113 await this . _client . sendNotification ( watcherNotification , {
81114 operation : 'setActive' ,
82115 file : this . _toSendData ( e ) ,
@@ -89,6 +122,10 @@ export class DocumentManager implements Disposable {
89122 check : boolean
90123 ) : Promise < void > {
91124 if ( this . _shouldSyncDocument ( e ) ) {
125+ debug ( 'documentOpen' , {
126+ filePath : sanitizeFilePath ( e . uri . fsPath ) ,
127+ check,
128+ } ) ;
92129 await this . _client . sendNotification ( watcherNotification , {
93130 operation : 'open' ,
94131 file : this . _toSendData ( e ) ,
@@ -99,6 +136,9 @@ export class DocumentManager implements Disposable {
99136
100137 private async _onDocumentClose ( e : PartialDocument ) : Promise < void > {
101138 if ( this . _shouldSyncDocument ( e ) ) {
139+ debug ( 'documentClose' , {
140+ filePath : sanitizeFilePath ( e . uri . fsPath ) ,
141+ } ) ;
102142 await this . _client . sendNotification ( watcherNotification , {
103143 operation : 'close' ,
104144 file : this . _toSendData ( e ) ,
@@ -107,6 +147,7 @@ export class DocumentManager implements Disposable {
107147 }
108148
109149 public async watch ( ) : Promise < void > {
150+ debug ( 'watch' , 'Starting document watch' ) ;
110151 await Promise . all (
111152 vscode . workspace . textDocuments . map ( ( doc ) => {
112153 return this . _onDocumentOpen ( doc , false ) ;
@@ -153,6 +194,7 @@ export class DocumentManager implements Disposable {
153194 }
154195
155196 public dispose ( ) : void {
197+ debug ( 'dispose' , 'Disposing document manager' ) ;
156198 this . _disposables . forEach ( ( d ) => void d . dispose ( ) ) ;
157199 this . _disposables = [ ] ;
158200 }
0 commit comments