Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
37efd5cc
V
vscode
项目概览
掘金者说
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
37efd5cc
编写于
2月 15, 2019
作者:
M
Martin Aeschlimann
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
resources: new APIs: relativePath, hasTrailingPathSeparator, removeTrailingPathSeparator
上级
33ef6896
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
151 addition
and
21 deletion
+151
-21
src/vs/base/common/resources.ts
src/vs/base/common/resources.ts
+49
-11
src/vs/base/test/common/resources.test.ts
src/vs/base/test/common/resources.test.ts
+99
-1
src/vs/code/electron-main/windows.ts
src/vs/code/electron-main/windows.ts
+3
-9
未找到文件。
src/vs/base/common/resources.ts
浏览文件 @
37efd5cc
...
...
@@ -35,20 +35,19 @@ export function isEqualOrParent(base: URI, parentCandidate: URI, ignoreCase = ha
if
(
base
.
scheme
===
Schemas
.
file
)
{
return
extpath
.
isEqualOrParent
(
fsPath
(
base
),
fsPath
(
parentCandidate
),
ignoreCase
);
}
if
(
isEqualAuthority
(
base
.
authority
,
parentCandidate
.
authority
,
ignoreCase
))
{
if
(
isEqualAuthority
(
base
.
authority
,
parentCandidate
.
authority
))
{
return
extpath
.
isEqualOrParent
(
base
.
path
,
parentCandidate
.
path
,
ignoreCase
,
'
/
'
);
}
}
return
false
;
}
function
isEqualAuthority
(
a1
:
string
,
a2
:
string
,
ignoreCase
?:
boolean
)
{
return
a1
===
a2
||
ignoreCase
&&
a1
&&
a2
&&
equalsIgnoreCase
(
a1
,
a2
);
function
isEqualAuthority
(
a1
:
string
,
a2
:
string
)
{
return
a1
===
a2
||
equalsIgnoreCase
(
a1
,
a2
);
}
export
function
isEqual
(
first
:
URI
|
undefined
,
second
:
URI
|
undefined
,
ignoreCase
=
hasToIgnoreCase
(
first
)):
boolean
{
const
identityEquals
=
(
first
===
second
);
if
(
identityEquals
)
{
if
(
first
===
second
)
{
return
true
;
}
...
...
@@ -56,11 +55,12 @@ export function isEqual(first: URI | undefined, second: URI | undefined, ignoreC
return
false
;
}
if
(
ignoreCase
)
{
return
equalsIgnoreCase
(
first
.
toString
(),
second
.
toString
())
;
if
(
first
.
scheme
!==
second
.
scheme
||
!
isEqualAuthority
(
first
.
authority
,
second
.
authority
)
)
{
return
false
;
}
return
first
.
toString
()
===
second
.
toString
();
const
p1
=
first
.
path
||
'
/
'
,
p2
=
second
.
path
||
'
/
'
;
return
p1
===
p2
||
ignoreCase
&&
equalsIgnoreCase
(
p1
||
'
/
'
,
p2
||
'
/
'
);
}
export
function
basename
(
resource
:
URI
):
string
{
...
...
@@ -106,7 +106,7 @@ export function joinPath(resource: URI, ...pathFragment: string[]): URI {
if
(
resource
.
scheme
===
Schemas
.
file
)
{
joinedPath
=
URI
.
file
(
paths
.
join
(
fsPath
(
resource
),
...
pathFragment
)).
path
;
}
else
{
joinedPath
=
paths
.
posix
.
join
(
resource
.
path
,
...
pathFragment
);
joinedPath
=
paths
.
posix
.
join
(
resource
.
path
||
'
/
'
,
...
pathFragment
);
}
return
resource
.
with
({
path
:
joinedPath
...
...
@@ -165,10 +165,48 @@ export function fsPath(uri: URI): string {
* Returns true if the URI path is absolute.
*/
export
function
isAbsolutePath
(
resource
:
URI
):
boolean
{
return
!!
resource
.
path
&&
resource
.
path
[
0
]
===
'
/
'
;
}
/**
* Returns true if the URI path has a trailing path separator
*/
export
function
hasTrailingPathSeparator
(
resource
:
URI
):
boolean
{
if
(
resource
.
scheme
===
Schemas
.
file
)
{
return
paths
.
isAbsolute
(
fsPath
(
resource
));
const
fsp
=
fsPath
(
resource
);
return
fsp
.
length
>
extpath
.
getRoot
(
fsp
).
length
&&
fsp
[
fsp
.
length
-
1
]
===
paths
.
sep
;
}
else
{
let
p
=
resource
.
path
;
return
p
.
length
>
1
&&
p
.
charCodeAt
(
p
.
length
-
1
)
===
CharCode
.
Slash
;
// ignore the slash at offset 0
}
}
/**
* Removes a trailing path seperator, if theres one.
* Important: Doesn't remove the first slash, it would make the URI invalid
*/
export
function
removeTrailingPathSeparator
(
resource
:
URI
):
URI
{
if
(
hasTrailingPathSeparator
(
resource
))
{
return
resource
.
with
({
path
:
resource
.
path
.
substr
(
0
,
resource
.
path
.
length
-
1
)
});
}
return
resource
;
}
/**
* Returns a relative path between two URIs. If the URIs don't have the same schema or authority, `undefined` is returned.
* The returned relative path always uses forward slashes.
*/
export
function
relativePath
(
from
:
URI
,
to
:
URI
):
string
|
undefined
{
if
(
from
.
scheme
!==
to
.
scheme
||
!
isEqualAuthority
(
from
.
authority
,
to
.
authority
))
{
return
undefined
;
}
if
(
from
.
scheme
===
Schemas
.
file
)
{
const
relativePath
=
paths
.
relative
(
from
.
path
,
to
.
path
);
return
isWindows
?
extpath
.
toForwardSlashes
(
relativePath
)
:
relativePath
;
}
return
paths
.
posix
.
isAbsolute
(
resource
.
path
);
return
paths
.
posix
.
relative
(
from
.
path
||
'
/
'
,
to
.
path
||
'
/
'
);
}
export
function
distinctParents
<
T
>
(
items
:
T
[],
resourceAccessor
:
(
item
:
T
)
=>
URI
):
T
[]
{
...
...
src/vs/base/test/common/resources.test.ts
浏览文件 @
37efd5cc
...
...
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
*
as
assert
from
'
assert
'
;
import
{
dirname
,
basename
,
distinctParents
,
joinPath
,
isEqual
,
isEqualOrParent
,
hasToIgnoreCase
,
normalizePath
,
isAbsolutePath
,
isMalformedFileUri
}
from
'
vs/base/common/resources
'
;
import
{
dirname
,
basename
,
distinctParents
,
joinPath
,
isEqual
,
isEqualOrParent
,
hasToIgnoreCase
,
normalizePath
,
isAbsolutePath
,
isMalformedFileUri
,
relativePath
,
removeTrailingPathSeparator
,
hasTrailingPathSeparator
}
from
'
vs/base/common/resources
'
;
import
{
URI
,
setUriThrowOnMissingScheme
}
from
'
vs/base/common/uri
'
;
import
{
isWindows
}
from
'
vs/base/common/platform
'
;
...
...
@@ -166,6 +166,102 @@ suite('Resources', () => {
assert
.
equal
(
isAbsolutePath
(
URI
.
parse
(
'
foo://a/foo/.
'
)),
true
);
});
function
assertTrailingSeparator
(
u1
:
URI
,
expected
:
boolean
)
{
assert
.
equal
(
hasTrailingPathSeparator
(
u1
),
expected
,
u1
.
toString
());
}
function
assertRemoveTrailingSeparator
(
u1
:
URI
,
expected
:
URI
)
{
assertEqualURI
(
removeTrailingPathSeparator
(
u1
),
expected
,
u1
.
toString
());
}
test
(
'
trailingPathSeparator
'
,
()
=>
{
assertTrailingSeparator
(
URI
.
parse
(
'
foo://a/foo
'
),
false
);
assertTrailingSeparator
(
URI
.
parse
(
'
foo://a/foo/
'
),
true
);
assertTrailingSeparator
(
URI
.
parse
(
'
foo://a/
'
),
false
);
assertTrailingSeparator
(
URI
.
parse
(
'
foo://a
'
),
false
);
assertRemoveTrailingSeparator
(
URI
.
parse
(
'
foo://a/foo
'
),
URI
.
parse
(
'
foo://a/foo
'
));
assertRemoveTrailingSeparator
(
URI
.
parse
(
'
foo://a/foo/
'
),
URI
.
parse
(
'
foo://a/foo
'
));
assertRemoveTrailingSeparator
(
URI
.
parse
(
'
foo://a/
'
),
URI
.
parse
(
'
foo://a/
'
));
assertRemoveTrailingSeparator
(
URI
.
parse
(
'
foo://a
'
),
URI
.
parse
(
'
foo://a
'
));
if
(
isWindows
)
{
assertTrailingSeparator
(
URI
.
file
(
'
c:
\\
a
\\
foo
'
),
false
);
assertTrailingSeparator
(
URI
.
file
(
'
c:
\\
a
\\
foo
\\
'
),
true
);
assertTrailingSeparator
(
URI
.
file
(
'
c:
\\
'
),
false
);
assertTrailingSeparator
(
URI
.
file
(
'
\\\\
server
\\
share
\\
some
\\
'
),
true
);
assertTrailingSeparator
(
URI
.
file
(
'
\\\\
server
\\
share
\\
'
),
false
);
assertRemoveTrailingSeparator
(
URI
.
file
(
'
c:
\\
a
\\
foo
'
),
URI
.
file
(
'
c:
\\
a
\\
foo
'
));
assertRemoveTrailingSeparator
(
URI
.
file
(
'
c:
\\
a
\\
foo
\\
'
),
URI
.
file
(
'
c:
\\
a
\\
foo
'
));
assertRemoveTrailingSeparator
(
URI
.
file
(
'
c:
\\
'
),
URI
.
file
(
'
c:
\\
'
));
assertRemoveTrailingSeparator
(
URI
.
file
(
'
\\\\
server
\\
share
\\
some
\\
'
),
URI
.
file
(
'
\\\\
server
\\
share
\\
some
'
));
assertRemoveTrailingSeparator
(
URI
.
file
(
'
\\\\
server
\\
share
\\
'
),
URI
.
file
(
'
\\\\
server
\\
share
\\
'
));
}
else
{
assertTrailingSeparator
(
URI
.
file
(
'
/foo/bar
'
),
false
);
assertTrailingSeparator
(
URI
.
file
(
'
/foo/bar/
'
),
true
);
assertTrailingSeparator
(
URI
.
file
(
'
/
'
),
false
);
assertRemoveTrailingSeparator
(
URI
.
file
(
'
/foo/bar
'
),
URI
.
file
(
'
/foo/bar
'
));
assertRemoveTrailingSeparator
(
URI
.
file
(
'
/foo/bar/
'
),
URI
.
file
(
'
/foo/bar
'
));
assertRemoveTrailingSeparator
(
URI
.
file
(
'
/
'
),
URI
.
file
(
'
/
'
));
}
});
function
assertEqualURI
(
actual
:
URI
,
expected
:
URI
,
message
?:
string
)
{
if
(
!
isEqual
(
expected
,
actual
))
{
assert
.
equal
(
expected
.
toString
(),
actual
.
toString
(),
message
);
}
}
function
assertRelativePath
(
u1
:
URI
,
u2
:
URI
,
expectedPath
:
string
|
undefined
,
ignoreJoin
?:
boolean
)
{
assert
.
equal
(
relativePath
(
u1
,
u2
),
expectedPath
,
`from
${
u1
.
toString
()}
to
${
u2
.
toString
()}
`
);
if
(
expectedPath
!==
undefined
&&
!
ignoreJoin
)
{
assertEqualURI
(
removeTrailingPathSeparator
(
joinPath
(
u1
,
expectedPath
)),
removeTrailingPathSeparator
(
u2
),
'
joinPath on relativePath should be equal
'
);
}
}
test
(
'
relativePath
'
,
()
=>
{
assertRelativePath
(
URI
.
parse
(
'
foo://a/foo
'
),
URI
.
parse
(
'
foo://a/foo/bar
'
),
'
bar
'
);
assertRelativePath
(
URI
.
parse
(
'
foo://a/foo
'
),
URI
.
parse
(
'
foo://a/foo/bar/
'
),
'
bar
'
);
assertRelativePath
(
URI
.
parse
(
'
foo://a/foo
'
),
URI
.
parse
(
'
foo://a/foo/bar/goo
'
),
'
bar/goo
'
);
assertRelativePath
(
URI
.
parse
(
'
foo://a/
'
),
URI
.
parse
(
'
foo://a/foo/bar/goo
'
),
'
foo/bar/goo
'
);
assertRelativePath
(
URI
.
parse
(
'
foo://a/foo/xoo
'
),
URI
.
parse
(
'
foo://a/foo/bar
'
),
'
../bar
'
);
assertRelativePath
(
URI
.
parse
(
'
foo://a/foo/xoo/yoo
'
),
URI
.
parse
(
'
foo://a
'
),
'
../../..
'
);
assertRelativePath
(
URI
.
parse
(
'
foo://a/foo
'
),
URI
.
parse
(
'
foo://a/foo/
'
),
''
);
assertRelativePath
(
URI
.
parse
(
'
foo://a/foo/
'
),
URI
.
parse
(
'
foo://a/foo
'
),
''
);
assertRelativePath
(
URI
.
parse
(
'
foo://a/foo/
'
),
URI
.
parse
(
'
foo://a/foo/
'
),
''
);
assertRelativePath
(
URI
.
parse
(
'
foo://a/foo
'
),
URI
.
parse
(
'
foo://a/foo
'
),
''
);
assertRelativePath
(
URI
.
parse
(
'
foo://a
'
),
URI
.
parse
(
'
foo://a
'
),
''
);
assertRelativePath
(
URI
.
parse
(
'
foo://a/
'
),
URI
.
parse
(
'
foo://a/
'
),
''
);
assertRelativePath
(
URI
.
parse
(
'
foo://a/
'
),
URI
.
parse
(
'
foo://a
'
),
''
);
assertRelativePath
(
URI
.
parse
(
'
foo://a/foo?q
'
),
URI
.
parse
(
'
foo://a/foo/bar#h
'
),
'
bar
'
);
assertRelativePath
(
URI
.
parse
(
'
foo://
'
),
URI
.
parse
(
'
foo://a/b
'
),
undefined
);
assertRelativePath
(
URI
.
parse
(
'
foo://a2/b
'
),
URI
.
parse
(
'
foo://a/b
'
),
undefined
);
assertRelativePath
(
URI
.
parse
(
'
goo://a/b
'
),
URI
.
parse
(
'
foo://a/b
'
),
undefined
);
if
(
isWindows
)
{
assertRelativePath
(
URI
.
file
(
'
c:
\\
foo
\\
bar
'
),
URI
.
file
(
'
c:
\\
foo
\\
bar
'
),
''
);
assertRelativePath
(
URI
.
file
(
'
c:
\\
foo
\\
bar
\\
huu
'
),
URI
.
file
(
'
c:
\\
foo
\\
bar
'
),
'
..
'
);
assertRelativePath
(
URI
.
file
(
'
c:
\\
foo
\\
bar
\\
a1
\\
a2
'
),
URI
.
file
(
'
c:
\\
foo
\\
bar
'
),
'
../..
'
);
assertRelativePath
(
URI
.
file
(
'
c:
\\
foo
\\
bar
\\
'
),
URI
.
file
(
'
c:
\\
foo
\\
bar
\\
a1
\\
a2
'
),
'
a1/a2
'
);
assertRelativePath
(
URI
.
file
(
'
c:
\\
foo
\\
bar
\\
'
),
URI
.
file
(
'
c:
\\
foo
\\
bar
\\
a1
\\
a2
\\
'
),
'
a1/a2
'
);
assertRelativePath
(
URI
.
file
(
'
c:
\\
'
),
URI
.
file
(
'
c:
\\
foo
\\
bar
'
),
'
foo/bar
'
);
assertRelativePath
(
URI
.
file
(
'
\\\\
server
\\
share
\\
some
\\
'
),
URI
.
file
(
'
\\\\
server
\\
share
\\
some
\\
path
'
),
'
path
'
);
assertRelativePath
(
URI
.
file
(
'
\\\\
server
\\
share
\\
some
\\
'
),
URI
.
file
(
'
\\\\
server
\\
share2
\\
some
\\
path
'
),
'
../../share2/some/path
'
,
true
);
// ignore joinPath assert: path.join is not root aware
}
else
{
assertRelativePath
(
URI
.
file
(
'
/a/foo
'
),
URI
.
file
(
'
/a/foo/bar
'
),
'
bar
'
);
assertRelativePath
(
URI
.
file
(
'
/a/foo
'
),
URI
.
file
(
'
/a/foo/bar/
'
),
'
bar
'
);
assertRelativePath
(
URI
.
file
(
'
/a/foo
'
),
URI
.
file
(
'
/a/foo/bar/goo
'
),
'
bar/goo
'
);
assertRelativePath
(
URI
.
file
(
'
/a/
'
),
URI
.
file
(
'
/a/foo/bar/goo
'
),
'
foo/bar/goo
'
);
assertRelativePath
(
URI
.
file
(
'
/
'
),
URI
.
file
(
'
/a/foo/bar/goo
'
),
'
a/foo/bar/goo
'
);
assertRelativePath
(
URI
.
file
(
'
/a/foo/xoo
'
),
URI
.
file
(
'
/a/foo/bar
'
),
'
../bar
'
);
assertRelativePath
(
URI
.
file
(
'
/a/foo/xoo/yoo
'
),
URI
.
file
(
'
/a
'
),
'
../../..
'
);
assertRelativePath
(
URI
.
file
(
'
/a/foo
'
),
URI
.
file
(
'
/a/foo/
'
),
''
);
assertRelativePath
(
URI
.
file
(
'
/a/foo
'
),
URI
.
file
(
'
/b/foo/
'
),
'
../../b/foo
'
);
}
});
test
(
'
isEqual
'
,
()
=>
{
let
fileURI
=
isWindows
?
URI
.
file
(
'
c:
\\
foo
\\
bar
'
)
:
URI
.
file
(
'
/foo/bar
'
);
let
fileURI2
=
isWindows
?
URI
.
file
(
'
C:
\\
foo
\\
Bar
'
)
:
URI
.
file
(
'
/foo/Bar
'
);
...
...
@@ -184,6 +280,8 @@ suite('Resources', () => {
assert
.
equal
(
isEqual
(
fileURI3
,
fileURI4
,
false
),
false
);
assert
.
equal
(
isEqual
(
fileURI
,
fileURI3
,
true
),
false
);
assert
.
equal
(
isEqual
(
URI
.
parse
(
'
foo://server
'
),
URI
.
parse
(
'
foo://server/
'
)),
true
);
});
test
(
'
isEqualOrParent
'
,
()
=>
{
...
...
src/vs/code/electron-main/windows.ts
浏览文件 @
37efd5cc
...
...
@@ -34,8 +34,7 @@ import { normalizeNFC } from 'vs/base/common/normalization';
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
Queue
,
timeout
}
from
'
vs/base/common/async
'
;
import
{
exists
}
from
'
vs/base/node/pfs
'
;
import
{
getComparisonKey
,
isEqual
,
normalizePath
,
basename
as
resourcesBasename
,
fsPath
}
from
'
vs/base/common/resources
'
;
import
{
endsWith
}
from
'
vs/base/common/strings
'
;
import
{
getComparisonKey
,
isEqual
,
normalizePath
,
basename
as
resourcesBasename
,
fsPath
,
hasTrailingPathSeparator
,
removeTrailingPathSeparator
}
from
'
vs/base/common/resources
'
;
import
{
getRemoteAuthority
}
from
'
vs/platform/remote/common/remoteHosts
'
;
import
{
restoreWindowsState
,
WindowsStateStorageData
,
getWindowsStateStoreData
}
from
'
vs/code/electron-main/windowsStateStorage
'
;
...
...
@@ -979,13 +978,8 @@ export class WindowsManager implements IWindowsMainService {
// remove trailing slash
const
uriPath
=
uri
.
path
;
if
(
endsWith
(
uriPath
,
'
/
'
))
{
if
(
uriPath
.
length
>
2
)
{
// only remove if the path has some content
uri
=
uri
.
with
({
path
:
uriPath
.
substr
(
0
,
uriPath
.
length
-
1
)
});
}
if
(
hasTrailingPathSeparator
(
uri
))
{
uri
=
removeTrailingPathSeparator
(
uri
);
if
(
!
typeHint
)
{
typeHint
=
'
folder
'
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录