Fix #2551 : Code coverage disappears when typing a character (#2853)

diff --git a/src/goCover.ts b/src/goCover.ts
index 2ad8e54..d05b9c4 100644
--- a/src/goCover.ts
+++ b/src/goCover.ts
@@ -29,6 +29,10 @@
 	coveredGutterStyle: string;
 	uncoveredGutterStyle: string;
 };
+// a list of modified, unsaved go files with actual code edits (rather than comment edits)
+let modifiedFiles: {
+	[key: string]: boolean;
+};
 
 /**
  * Initializes the decorators used for Code coverage.
@@ -288,11 +292,32 @@
 }
 
 /**
- * Listener for change in the editor.
- * A change in a Go file means the coverage data is stale. Therefore it should be cleared.
+ * Listener for file save that clears potential stale coverage data.
+ * Local cache tracks files with changes outside of comments to determine
+ * files for which the save event can cause stale coverage data.
+ * @param e TextDocument
+ */
+export function removeCodeCoverageOnFileSave(e: vscode.TextDocument) {
+	if (e.languageId !== 'go' || !isCoverageApplied || !e.isDirty) {
+		return;
+	}
+
+	if (vscode.window.visibleTextEditors.every((editor) => editor.document !== e)) {
+		return;
+	}
+
+	if (modifiedFiles[e.fileName]) {
+		clearCoverage();
+		modifiedFiles = {}; // reset the list of modified files
+	}
+}
+
+/**
+ * Listener for file change that tracks files with changes outside of comments
+ * to determine files for which an eventual save can cause stale coverage data.
  * @param e TextDocumentChangeEvent
  */
-export function removeCodeCoverageOnFileChange(e: vscode.TextDocumentChangeEvent) {
+export function trackCodeCoverageRemovalOnFileChange(e: vscode.TextDocumentChangeEvent) {
 	if (e.document.languageId !== 'go' || !e.contentChanges.length || !isCoverageApplied) {
 		return;
 	}
@@ -305,7 +330,7 @@
 		return;
 	}
 
-	clearCoverage();
+	modifiedFiles[e.document.fileName] = true;
 }
 
 /**
diff --git a/src/goMain.ts b/src/goMain.ts
index 4620a39..64145be 100644
--- a/src/goMain.ts
+++ b/src/goMain.ts
@@ -16,8 +16,9 @@
 	applyCodeCoverage,
 	applyCodeCoverageToAllEditors,
 	initCoverageDecorators,
-	removeCodeCoverageOnFileChange,
+	removeCodeCoverageOnFileSave,
 	toggleCoverageCurrentPackage,
+	trackCodeCoverageRemovalOnFileChange,
 	updateCodeCoverageDecorators
 } from './goCover';
 import { GoDebugConfigurationProvider } from './goDebugConfiguration';
@@ -575,6 +576,7 @@
 }
 
 function addOnSaveTextDocumentListeners(ctx: vscode.ExtensionContext) {
+	vscode.workspace.onDidSaveTextDocument(removeCodeCoverageOnFileSave, null, ctx.subscriptions);
 	vscode.workspace.onDidSaveTextDocument(
 		(document) => {
 			if (document.languageId !== 'go') {
@@ -607,7 +609,7 @@
 }
 
 function addOnChangeTextDocumentListeners(ctx: vscode.ExtensionContext) {
-	vscode.workspace.onDidChangeTextDocument(removeCodeCoverageOnFileChange, null, ctx.subscriptions);
+	vscode.workspace.onDidChangeTextDocument(trackCodeCoverageRemovalOnFileChange, null, ctx.subscriptions);
 	vscode.workspace.onDidChangeTextDocument(removeTestStatus, null, ctx.subscriptions);
 	vscode.workspace.onDidChangeTextDocument(notifyIfGeneratedFile, ctx, ctx.subscriptions);
 }