diff --git a/src/Microsoft.SqlTools.ServiceLayer/Workspace/Workspace.cs b/src/Microsoft.SqlTools.ServiceLayer/Workspace/Workspace.cs
index e3954d39..c2beb65b 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Workspace/Workspace.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Workspace/Workspace.cs
@@ -48,6 +48,23 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
#region Public Methods
+ ///
+ /// Checks if a given URI is contained in a workspace
+ ///
+ ///
+ /// Flag indicating if the file is tracked in workspace
+ public bool ContainsFile(string filePath)
+ {
+ Validate.IsNotNullOrWhitespaceString("filePath", filePath);
+
+ // Resolve the full file path
+ string resolvedFilePath = this.ResolveFilePath(filePath);
+ string keyName = resolvedFilePath.ToLower();
+
+ ScriptFile scriptFile = null;
+ return this.workspaceFiles.TryGetValue(keyName, out scriptFile);
+ }
+
///
/// Gets an open file in the workspace. If the file isn't open but
/// exists on the filesystem, load and return it. Virtual method to
@@ -124,9 +141,10 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
// with 'inmemory'. Untitled files which have been marked of
// type SqlTools have a path starting with 'untitled'.
return
- filePath.StartsWith("inmemory") ||
- filePath.StartsWith("tsqloutput") ||
- filePath.StartsWith("untitled");
+ filePath.StartsWith("inmemory:") ||
+ filePath.StartsWith("tsqloutput:") ||
+ filePath.StartsWith("git:") ||
+ filePath.StartsWith("untitled:");
}
///
diff --git a/src/Microsoft.SqlTools.ServiceLayer/Workspace/WorkspaceService.cs b/src/Microsoft.SqlTools.ServiceLayer/Workspace/WorkspaceService.cs
index 5b5102e9..c3b6b672 100644
--- a/src/Microsoft.SqlTools.ServiceLayer/Workspace/WorkspaceService.cs
+++ b/src/Microsoft.SqlTools.ServiceLayer/Workspace/WorkspaceService.cs
@@ -244,6 +244,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
{
Logger.Write(LogLevel.Verbose, "HandleDidOpenTextDocumentNotification");
+ if (IsScmEvent(openParams.TextDocument.Uri))
+ {
+ return;
+ }
+
// read the SQL file contents into the ScriptFile
ScriptFile openedFile = Workspace.GetFileBuffer(openParams.TextDocument.Uri, openParams.TextDocument.Text);
@@ -260,6 +265,11 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
{
Logger.Write(LogLevel.Verbose, "HandleDidCloseTextDocumentNotification");
+ if (IsScmEvent(closeParams.TextDocument.Uri))
+ {
+ return;
+ }
+
// Skip closing this file if the file doesn't exist
var closedFile = Workspace.GetFile(closeParams.TextDocument.Uri);
if (closedFile == null)
@@ -311,6 +321,12 @@ namespace Microsoft.SqlTools.ServiceLayer.Workspace
EndOffset = changeRange.End.Character + 1
};
}
+
+ internal static bool IsScmEvent(string filePath)
+ {
+ // if the URI is prefixed with git: then we want to skip processing that file
+ return filePath.StartsWith("git:");
+ }
#endregion
}
diff --git a/test/Microsoft.SqlTools.ServiceLayer.Test/Workspace/WorkspaceTests.cs b/test/Microsoft.SqlTools.ServiceLayer.Test/Workspace/WorkspaceTests.cs
index df63e816..0f34802a 100644
--- a/test/Microsoft.SqlTools.ServiceLayer.Test/Workspace/WorkspaceTests.cs
+++ b/test/Microsoft.SqlTools.ServiceLayer.Test/Workspace/WorkspaceTests.cs
@@ -145,5 +145,56 @@ namespace Microsoft.SqlTools.ServiceLayer.Test.Workspace
Assert.NotNull(workspace.ResolveRelativeScriptPath(@"c:\path\", "file.sql"));
});
}
+
+ [Fact]
+ public async Task DontProcessGitFileEvents()
+ {
+ // setup test workspace
+ var workspace = new ServiceLayer.Workspace.Workspace();
+ var workspaceService = new WorkspaceService {Workspace = workspace};
+
+ // send a document open event with git:/ prefix URI
+ string filePath = "git:/myfile.sql";
+ var openParams = new DidOpenTextDocumentNotification
+ {
+ TextDocument = new TextDocumentItem { Uri = filePath }
+ };
+
+ await workspaceService.HandleDidOpenTextDocumentNotification(openParams, eventContext: null);
+
+ // verify the file is not being tracked by workspace
+ Assert.False(workspaceService.Workspace.ContainsFile(filePath));
+
+ // send a close event with git:/ prefix URI
+ var closeParams = new DidCloseTextDocumentParams
+ {
+ TextDocument = new TextDocumentItem { Uri = filePath }
+ };
+
+ await workspaceService.HandleDidCloseTextDocumentNotification(closeParams, eventContext: null);
+
+ // this is not that interesting validation since the open is ignored
+ // the main validation is that close doesn't raise an exception
+ Assert.False(workspaceService.Workspace.ContainsFile(filePath));
+ }
+
+ [Fact]
+ public async Task WorkspaceContainsFile()
+ {
+ var workspace = new ServiceLayer.Workspace.Workspace();
+ var workspaceService = new WorkspaceService {Workspace = workspace};
+ var openedFile = workspace.GetFileBuffer(TestObjects.ScriptUri, string.Empty);
+
+ // send a document open event
+ var openParams = new DidOpenTextDocumentNotification
+ {
+ TextDocument = new TextDocumentItem { Uri = TestObjects.ScriptUri }
+ };
+
+ await workspaceService.HandleDidOpenTextDocumentNotification(openParams, eventContext: null);
+
+ // verify the file is being tracked by workspace
+ Assert.True(workspaceService.Workspace.ContainsFile(TestObjects.ScriptUri));
+ }
}
}