/// <summary> /// Gets a new TextDocument instance which is identified by the given file /// path and initially contains the given buffer contents. /// </summary> /// <param name="path"></param> /// <param name="initialBuffer"></param> /// <returns></returns> public TextDocument GetFileBuffer(string path, string initialBuffer) { Validate.IsNotNullOrWhitespaceString("path", path); if (IsNonFileUri(path)) { return(null); } // Resolve the full file path ResolvedFile resolvedFile = this.ResolveFilePath(path); string keyName = resolvedFile.LowercaseFilePath; // Make sure the file isn't already loaded into the workspace TextDocument document = null; if (!this.Documents.TryGetValue(keyName, out document)) { document = new TextDocument(resolvedFile.FilePath, path, initialBuffer); this.Documents.Add(keyName, document); Logger.Instance.Write(LogLevel.Verbose, "Opened file as in-memory buffer: " + resolvedFile.FilePath); } return(document); }
/// <summary> /// Checks if a given URI is contained in a workspace /// </summary> /// <param name="path"></param> /// <returns>Flag indicating if the file is tracked in workspace</returns> public bool ContainsFile(string path) { Validate.IsNotNullOrWhitespaceString("path", path); // Resolve the full file path ResolvedFile resolvedFile = this.ResolveFilePath(path); string keyName = resolvedFile.LowercaseFilePath; TextDocument document = null; return(this.Documents.TryGetValue(keyName, out document)); }
private ResolvedFile ResolveFilePath(string path) { bool canReadFromDisk = false; if (!IsPathInMemoryOrNonFileUri(path)) { if (path.StartsWith(@"file://")) { // VS Code encodes the ':' character in the drive name, which can lead to problems parsing // the URI, so unencode it if present. See https://github.com/Microsoft/vscode/issues/2990 path = path.Replace("%3A/", ":/", StringComparison.OrdinalIgnoreCase); // Client sent the path in URI format, extract the local path and trim // any extraneous slashes Uri fileUri = new Uri(path); path = fileUri.LocalPath; if (path.StartsWith("//") || path.StartsWith("\\\\") || path.StartsWith("/")) { path = path.Substring(1); } } // Clients could specify paths with escaped space, [ and ] characters which .NET APIs // will not handle. These paths will get appropriately escaped just before being passed // into the SqlTools engine. path = UnescapePath(path); // switch to unix path separators on non-Windows platforms if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { path = path.Replace('\\', '/'); } // Get the absolute file path ResolvedFile resolvedFile = ResolvedFile.TryGetFullPath(path); path = resolvedFile.FilePath; canReadFromDisk = resolvedFile.CanReadFromDisk; } Logger.Instance.Write(LogLevel.Verbose, "Resolved path: " + path); return(new ResolvedFile(path, canReadFromDisk)); }
/// <summary> /// 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 /// allow for mocking /// </summary> /// <param name="path">The file path at which the document resides.</param> /// <exception cref="FileNotFoundException"> /// <paramref name="path"/> is not found. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="path"/> contains a null or empty string. /// </exception> public virtual TextDocument GetFile(string path) { Validate.IsNotNullOrWhitespaceString("path", path); if (IsNonFileUri(path)) { return(null); } // Resolve the full file path ResolvedFile resolvedFile = this.ResolveFilePath(path); string keyName = resolvedFile.LowercaseFilePath; // Make sure the file isn't already loaded into the workspace TextDocument document = null; if (!this.Documents.TryGetValue(keyName, out document)) { if (IsUntitled(resolvedFile.FilePath) || !resolvedFile.CanReadFromDisk || !File.Exists(resolvedFile.FilePath)) { // It's either not a registered untitled file, or not a valid file on disk // so any attempt to read from disk will fail. return(null); } // This method allows FileNotFoundException to bubble up // if the file isn't found. using (FileStream fileStream = new FileStream(resolvedFile.FilePath, FileMode.Open, FileAccess.Read)) using (StreamReader streamReader = new StreamReader(fileStream, Encoding.UTF8)) { document = new TextDocument(resolvedFile.FilePath, path, streamReader, isInMemory: false); this.Documents.Add(keyName, document); } Logger.Instance.Write(LogLevel.Verbose, "Opened file on disk: " + resolvedFile.FilePath); } return(document); }