From ae769259269da95bb05cce8b858c907765cce0d8 Mon Sep 17 00:00:00 2001 From: Aleksei Gusev Date: Fri, 13 Jan 2017 20:27:02 +0300 Subject: [PATCH] Normalize disk drive letter in path on Windows Currently atom creates two buffers for the same file if passed paths use difference case for disk drive letter, e.g. d:\file.txt and D:\file.txt --- spec/default-directory-provider-spec.coffee | 9 +++++++++ spec/project-spec.coffee | 4 ++++ src/default-directory-provider.coffee | 14 +++++++++++++- src/project.coffee | 7 +++---- 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/spec/default-directory-provider-spec.coffee b/spec/default-directory-provider-spec.coffee index 821c278ee..114a91969 100644 --- a/spec/default-directory-provider-spec.coffee +++ b/spec/default-directory-provider-spec.coffee @@ -28,6 +28,15 @@ describe "DefaultDirectoryProvider", -> directory = provider.directoryForURISync(nonNormalizedPath) expect(directory.getPath()).toEqual tmp + it "normalizes disk drive letter in Windows path", -> + provider = new DefaultDirectoryProvider() + nonNormalizedPath = tmp[0].toLowerCase()+tmp.slice(1) + expect(!tmp.search(/^[a-z]:/)).toBe false + expect(!nonNormalizedPath.search(/^[a-z]:/)).toBe true + + directory = provider.directoryForURISync(nonNormalizedPath) + expect(directory.getPath()).toEqual tmp + it "creates a Directory for its parent dir when passed a file", -> provider = new DefaultDirectoryProvider() file = path.join(tmp, "example.txt") diff --git a/spec/project-spec.coffee b/spec/project-spec.coffee index d548255e5..f5eae519d 100644 --- a/spec/project-spec.coffee +++ b/spec/project-spec.coffee @@ -614,3 +614,7 @@ describe "Project", -> randomPath = path.join("some", "random", "path") expect(atom.project.contains(randomPath)).toBe false + + describe ".resolvePath(uri)", -> + it "normalizes disk drive letter in passed Windows path", -> + expect(atom.project.resolvePath("d:\file.txt")).toEqual "D:\file.txt" diff --git a/src/default-directory-provider.coffee b/src/default-directory-provider.coffee index ed4e9ba36..531f75180 100644 --- a/src/default-directory-provider.coffee +++ b/src/default-directory-provider.coffee @@ -15,7 +15,7 @@ class DefaultDirectoryProvider # * {Directory} if the given URI is compatible with this provider. # * `null` if the given URI is not compatibile with this provider. directoryForURISync: (uri) -> - normalizedPath = path.normalize(uri) + normalizedPath = @normalizePath(uri) {host} = url.parse(uri) directoryPath = if host uri @@ -42,3 +42,15 @@ class DefaultDirectoryProvider # * `null` if the given URI is not compatibile with this provider. directoryForURI: (uri) -> Promise.resolve(@directoryForURISync(uri)) + + # Public: Normalizes path. + # + # * `uri` {String} The path that should be normalized. + # + # Returns a {String} with normalized path. + normalizePath: (uri) -> + # Normalize disk drive letter on Windows to avoid opening two buffers for the same file + pathWithNormalizedDiskDriveLetter = uri + if matchData = uri.match(/^([A-Za-z]):/) + pathWithNormalizedDiskDriveLetter = "#{matchData[1].toUpperCase()}#{uri.slice(1)}" + path.normalize(pathWithNormalizedDiskDriveLetter) diff --git a/src/project.coffee b/src/project.coffee index 522fbfbc7..34e955598 100644 --- a/src/project.coffee +++ b/src/project.coffee @@ -205,7 +205,7 @@ class Project extends Model removePath: (projectPath) -> # The projectPath may be a URI, in which case it should not be normalized. unless projectPath in @getPaths() - projectPath = path.normalize(projectPath) + projectPath = @defaultDirectoryProvider.normalizePath(projectPath) indexToRemove = null for directory, i in @rootDirectories @@ -233,11 +233,10 @@ class Project extends Model uri else if fs.isAbsolute(uri) - path.normalize(fs.resolveHome(uri)) - + @defaultDirectoryProvider.normalizePath(fs.resolveHome(uri)) # TODO: what should we do here when there are multiple directories? else if projectPath = @getPaths()[0] - path.normalize(fs.resolveHome(path.join(projectPath, uri))) + @defaultDirectoryProvider.normalizePath(fs.resolveHome(path.join(projectPath, uri))) else undefined