Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
e9650bd5
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
e9650bd5
编写于
2月 05, 2018
作者:
B
Benjamin Pasero
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Unexpected events for single updateWorkspaceFolders operation (fixes #42639)
上级
73e61938
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
131 addition
and
65 deletion
+131
-65
src/vs/workbench/services/configuration/node/configurationService.ts
...bench/services/configuration/node/configurationService.ts
+65
-61
src/vs/workbench/services/configuration/test/node/configurationService.test.ts
...ices/configuration/test/node/configurationService.test.ts
+49
-0
src/vs/workbench/services/workspace/node/workspaceEditingService.ts
...kbench/services/workspace/node/workspaceEditingService.ts
+17
-4
未找到文件。
src/vs/workbench/services/configuration/node/configurationService.ts
浏览文件 @
e9650bd5
...
...
@@ -5,9 +5,8 @@
'
use strict
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
*
as
paths
from
'
vs/base/common/paths
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
dirname
}
from
'
path
'
;
import
{
dirname
,
basename
}
from
'
path
'
;
import
*
as
assert
from
'
vs/base/common/assert
'
;
import
Event
,
{
Emitter
}
from
'
vs/base/common/event
'
;
import
{
StrictResourceMap
}
from
'
vs/base/common/map
'
;
...
...
@@ -111,13 +110,16 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat
}
public
addFolders
(
foldersToAdd
:
IWorkspaceFolderCreationData
[],
index
?:
number
):
TPromise
<
void
>
{
assert
.
ok
(
this
.
jsonEditingService
,
'
Workbench is not initialized yet
'
);
return
this
.
workspaceEditingQueue
.
queue
(()
=>
this
.
doAddFolders
(
foldersToAdd
,
index
));
return
this
.
updateFolders
(
foldersToAdd
,
[],
index
);
}
public
removeFolders
(
foldersToRemove
:
URI
[]):
TPromise
<
void
>
{
return
this
.
updateFolders
([],
foldersToRemove
);
}
public
updateFolders
(
foldersToAdd
:
IWorkspaceFolderCreationData
[],
foldersToRemove
:
URI
[],
index
?:
number
):
TPromise
<
void
>
{
assert
.
ok
(
this
.
jsonEditingService
,
'
Workbench is not initialized yet
'
);
return
this
.
workspaceEditingQueue
.
queue
(()
=>
this
.
do
RemoveFolders
(
foldersToRemove
));
return
this
.
workspaceEditingQueue
.
queue
(()
=>
this
.
do
UpdateFolders
(
foldersToAdd
,
foldersToRemove
,
index
));
}
public
isInsideWorkspace
(
resource
:
URI
):
boolean
{
...
...
@@ -134,80 +136,82 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat
return
false
;
}
private
do
AddFolders
(
foldersToAdd
:
IWorkspaceFolderCreationData
[],
index
?:
number
):
TPromise
<
void
>
{
private
do
UpdateFolders
(
foldersToAdd
:
IWorkspaceFolderCreationData
[],
foldersToRemove
:
URI
[],
index
?:
number
):
TPromise
<
void
>
{
if
(
this
.
getWorkbenchState
()
!==
WorkbenchState
.
WORKSPACE
)
{
return
TPromise
.
as
(
void
0
);
// we need a workspace to begin with
}
const
currentWorkspaceFolders
=
this
.
getWorkspace
().
folders
;
const
currentWorkspaceFolderUris
=
currentWorkspaceFolders
.
map
(
folder
=>
folder
.
uri
);
const
currentStoredFolders
=
currentWorkspaceFolders
.
map
(
folder
=>
folder
.
raw
);
const
storedFoldersToAdd
:
IStoredWorkspaceFolder
[]
=
[];
if
(
foldersToAdd
.
length
+
foldersToRemove
.
length
===
0
)
{
return
TPromise
.
as
(
void
0
);
// nothing to do
}
const
workspaceConfigFolder
=
dirname
(
this
.
getWorkspace
().
configuration
.
fsPath
)
;
let
foldersHaveChanged
=
false
;
foldersToAdd
.
forEach
(
folderToAdd
=>
{
if
(
this
.
contains
(
currentWorkspaceFolderUris
,
folderToAdd
.
uri
))
{
return
;
// already existing
// Remove first (if any)
let
currentWorkspaceFolders
=
this
.
getWorkspace
().
folders
;
let
newStoredFolders
:
IStoredWorkspaceFolder
[]
=
currentWorkspaceFolders
.
map
(
f
=>
f
.
raw
).
filter
((
folder
,
index
)
=>
{
if
(
!
isStoredWorkspaceFolder
(
folder
))
{
return
true
;
// keep entries which are unrelated
}
let
storedFolder
:
IStoredWorkspaceFolder
;
return
!
this
.
contains
(
foldersToRemove
,
currentWorkspaceFolders
[
index
].
uri
);
// keep entries which are unrelated
});
// File resource: use "path" property
if
(
folderToAdd
.
uri
.
scheme
===
Schemas
.
file
)
{
storedFolder
=
{
path
:
massageFolderPathForWorkspace
(
folderToAdd
.
uri
.
fsPath
,
workspaceConfigFolder
,
currentStoredFolders
)
};
}
foldersHaveChanged
=
currentWorkspaceFolders
.
length
!==
newStoredFolders
.
length
;
// Any other resource: use "uri" property
else
{
storedFolder
=
{
uri
:
folderToAdd
.
uri
.
toString
(
true
)
};
}
// Add afterwards (if any)
if
(
foldersToAdd
.
length
)
{
if
(
folderToAdd
.
name
)
{
storedFolder
.
name
=
folderToAdd
.
name
;
}
// Recompute current workspace folders if we have folders to add
const
workspaceConfigFolder
=
dirname
(
this
.
getWorkspace
().
configuration
.
fsPath
);
currentWorkspaceFolders
=
toWorkspaceFolders
(
newStoredFolders
,
URI
.
file
(
workspaceConfigFolder
));
const
currentWorkspaceFolderUris
=
currentWorkspaceFolders
.
map
(
folder
=>
folder
.
uri
);
storedFoldersToAdd
.
push
(
storedFolder
);
});
const
storedFoldersToAdd
:
IStoredWorkspaceFolder
[]
=
[];
if
(
storedFoldersToAdd
.
length
>
0
)
{
let
newStoredWorkspaceFolders
:
IStoredWorkspaceFolder
[]
=
[];
foldersToAdd
.
forEach
(
folderToAdd
=>
{
if
(
this
.
contains
(
currentWorkspaceFolderUris
,
folderToAdd
.
uri
))
{
return
;
// already existing
}
if
(
typeof
index
===
'
number
'
&&
index
>=
0
&&
index
<
currentStoredFolders
.
length
)
{
newStoredWorkspaceFolders
=
currentStoredFolders
.
slice
(
0
);
newStoredWorkspaceFolders
.
splice
(
index
,
0
,
...
storedFoldersToAdd
);
}
else
{
newStoredWorkspaceFolders
=
[...
currentStoredFolders
,
...
storedFoldersToAdd
];
}
let
storedFolder
:
IStoredWorkspaceFolder
;
return
this
.
setFolders
(
newStoredWorkspaceFolders
);
}
// File resource: use "path" property
if
(
folderToAdd
.
uri
.
scheme
===
Schemas
.
file
)
{
storedFolder
=
{
path
:
massageFolderPathForWorkspace
(
folderToAdd
.
uri
.
fsPath
,
workspaceConfigFolder
,
newStoredFolders
)
};
}
return
TPromise
.
as
(
void
0
);
}
// Any other resource: use "uri" property
else
{
storedFolder
=
{
uri
:
folderToAdd
.
uri
.
toString
(
true
)
};
}
private
doRemoveFolders
(
foldersToRemove
:
URI
[]):
TPromise
<
void
>
{
if
(
this
.
getWorkbenchState
()
!==
WorkbenchState
.
WORKSPACE
)
{
return
TPromise
.
as
(
void
0
);
// we need a workspace to begin with
}
if
(
folderToAdd
.
name
)
{
storedFolder
.
name
=
folderToAdd
.
name
;
}
const
currentWorkspaceFolders
=
this
.
getWorkspace
().
folders
;
const
currentStoredFolders
=
currentWorkspaceFolders
.
map
(
folder
=>
folder
.
raw
);
storedFoldersToAdd
.
push
(
storedFolder
)
;
}
);
const
newStoredFolders
:
IStoredWorkspaceFolder
[]
=
currentStoredFolders
.
filter
((
folder
,
index
)
=>
{
if
(
!
isStoredWorkspaceFolder
(
folder
))
{
return
true
;
// keep entries which are unrelated
}
// Apply to array of newStoredFolders
if
(
storedFoldersToAdd
.
length
>
0
)
{
foldersHaveChanged
=
true
;
return
!
this
.
contains
(
foldersToRemove
,
currentWorkspaceFolders
[
index
].
uri
);
// keep entries which are unrelated
});
if
(
typeof
index
===
'
number
'
&&
index
>=
0
&&
index
<
newStoredFolders
.
length
)
{
newStoredFolders
=
newStoredFolders
.
slice
(
0
);
newStoredFolders
.
splice
(
index
,
0
,
...
storedFoldersToAdd
);
}
else
{
newStoredFolders
=
[...
newStoredFolders
,
...
storedFoldersToAdd
];
}
}
}
if
(
newStoredFolders
.
length
!==
currentStoredFolders
.
length
)
{
// Set folders if we recorded a change
if
(
foldersHaveChanged
)
{
return
this
.
setFolders
(
newStoredFolders
);
}
...
...
@@ -331,7 +335,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat
const
workspaceConfigPath
=
URI
.
file
(
workspaceIdentifier
.
configPath
);
return
this
.
workspaceConfiguration
.
load
(
workspaceConfigPath
)
.
then
(()
=>
{
const
workspaceFolders
=
toWorkspaceFolders
(
this
.
workspaceConfiguration
.
getFolders
(),
URI
.
file
(
paths
.
dirname
(
workspaceConfigPath
.
fsPath
)));
const
workspaceFolders
=
toWorkspaceFolders
(
this
.
workspaceConfiguration
.
getFolders
(),
URI
.
file
(
dirname
(
workspaceConfigPath
.
fsPath
)));
const
workspaceId
=
workspaceIdentifier
.
id
;
const
workspaceName
=
getWorkspaceLabel
({
id
:
workspaceId
,
configPath
:
workspaceConfigPath
.
fsPath
},
this
.
environmentService
);
return
new
Workspace
(
workspaceId
,
workspaceName
,
workspaceFolders
,
workspaceConfigPath
);
...
...
@@ -350,7 +354,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat
}
private
createEmptyWorkspace
(
configuration
:
IWindowConfiguration
):
TPromise
<
Workspace
>
{
let
id
=
configuration
.
backupPath
?
URI
.
from
({
path
:
paths
.
basename
(
configuration
.
backupPath
),
scheme
:
'
empty
'
}).
toString
()
:
''
;
let
id
=
configuration
.
backupPath
?
URI
.
from
({
path
:
basename
(
configuration
.
backupPath
),
scheme
:
'
empty
'
}).
toString
()
:
''
;
return
TPromise
.
as
(
new
Workspace
(
id
));
}
...
...
@@ -506,7 +510,7 @@ export class WorkspaceService extends Disposable implements IWorkspaceConfigurat
private
onWorkspaceConfigurationChanged
():
TPromise
<
void
>
{
if
(
this
.
workspace
&&
this
.
workspace
.
configuration
&&
this
.
_configuration
)
{
const
workspaceConfigurationChangeEvent
=
this
.
_configuration
.
compareAndUpdateWorkspaceConfiguration
(
this
.
workspaceConfiguration
.
getConfiguration
());
let
configuredFolders
=
toWorkspaceFolders
(
this
.
workspaceConfiguration
.
getFolders
(),
URI
.
file
(
paths
.
dirname
(
this
.
workspace
.
configuration
.
fsPath
)));
let
configuredFolders
=
toWorkspaceFolders
(
this
.
workspaceConfiguration
.
getFolders
(),
URI
.
file
(
dirname
(
this
.
workspace
.
configuration
.
fsPath
)));
const
changes
=
this
.
compareFolders
(
this
.
workspace
.
folders
,
configuredFolders
);
if
(
changes
.
added
.
length
||
changes
.
removed
.
length
||
changes
.
changed
.
length
)
{
this
.
workspace
.
folders
=
configuredFolders
;
...
...
src/vs/workbench/services/configuration/test/node/configurationService.test.ts
浏览文件 @
e9650bd5
...
...
@@ -274,6 +274,55 @@ suite('WorkspaceContextService - Workspace', () => {
});
});
test
(
'
update folders (remove last and add to end)
'
,
()
=>
{
const
target
=
sinon
.
spy
();
testObject
.
onDidChangeWorkspaceFolders
(
target
);
const
workspaceDir
=
path
.
dirname
(
testObject
.
getWorkspace
().
folders
[
0
].
uri
.
fsPath
);
const
addedFolders
=
[{
uri
:
URI
.
file
(
path
.
join
(
workspaceDir
,
'
d
'
))
},
{
uri
:
URI
.
file
(
path
.
join
(
workspaceDir
,
'
c
'
))
}];
const
removedFolders
=
[
testObject
.
getWorkspace
().
folders
[
1
]].
map
(
f
=>
f
.
uri
);
return
testObject
.
updateFolders
(
addedFolders
,
removedFolders
)
.
then
(()
=>
{
assert
.
ok
(
target
.
calledOnce
);
const
actual
=
<
IWorkspaceFoldersChangeEvent
>
target
.
args
[
0
][
0
];
assert
.
deepEqual
(
actual
.
added
.
map
(
r
=>
r
.
uri
.
toString
()),
addedFolders
.
map
(
a
=>
a
.
uri
.
toString
()));
assert
.
deepEqual
(
actual
.
removed
.
map
(
r
=>
r
.
uri
.
toString
()),
removedFolders
.
map
(
a
=>
a
.
toString
()));
assert
.
deepEqual
(
actual
.
changed
,
[]);
});
});
test
(
'
update folders (rename first via add and remove)
'
,
()
=>
{
const
target
=
sinon
.
spy
();
testObject
.
onDidChangeWorkspaceFolders
(
target
);
const
workspaceDir
=
path
.
dirname
(
testObject
.
getWorkspace
().
folders
[
0
].
uri
.
fsPath
);
const
addedFolders
=
[{
uri
:
URI
.
file
(
path
.
join
(
workspaceDir
,
'
a
'
)),
name
:
'
The Folder
'
}];
const
removedFolders
=
[
testObject
.
getWorkspace
().
folders
[
0
]].
map
(
f
=>
f
.
uri
);
return
testObject
.
updateFolders
(
addedFolders
,
removedFolders
,
0
)
.
then
(()
=>
{
assert
.
ok
(
target
.
calledOnce
);
const
actual
=
<
IWorkspaceFoldersChangeEvent
>
target
.
args
[
0
][
0
];
assert
.
deepEqual
(
actual
.
added
,
[]);
assert
.
deepEqual
(
actual
.
removed
,
[]);
assert
.
deepEqual
(
actual
.
changed
.
map
(
r
=>
r
.
uri
.
toString
()),
removedFolders
.
map
(
a
=>
a
.
toString
()));
});
});
test
(
'
update folders (remove first and add to end)
'
,
()
=>
{
const
target
=
sinon
.
spy
();
testObject
.
onDidChangeWorkspaceFolders
(
target
);
const
workspaceDir
=
path
.
dirname
(
testObject
.
getWorkspace
().
folders
[
0
].
uri
.
fsPath
);
const
addedFolders
=
[{
uri
:
URI
.
file
(
path
.
join
(
workspaceDir
,
'
d
'
))
},
{
uri
:
URI
.
file
(
path
.
join
(
workspaceDir
,
'
c
'
))
}];
const
removedFolders
=
[
testObject
.
getWorkspace
().
folders
[
0
]].
map
(
f
=>
f
.
uri
);
const
changedFolders
=
[
testObject
.
getWorkspace
().
folders
[
1
]].
map
(
f
=>
f
.
uri
);
return
testObject
.
updateFolders
(
addedFolders
,
removedFolders
)
.
then
(()
=>
{
assert
.
ok
(
target
.
calledOnce
);
const
actual
=
<
IWorkspaceFoldersChangeEvent
>
target
.
args
[
0
][
0
];
assert
.
deepEqual
(
actual
.
added
.
map
(
r
=>
r
.
uri
.
toString
()),
addedFolders
.
map
(
a
=>
a
.
uri
.
toString
()));
assert
.
deepEqual
(
actual
.
removed
.
map
(
r
=>
r
.
uri
.
toString
()),
removedFolders
.
map
(
a
=>
a
.
toString
()));
assert
.
deepEqual
(
actual
.
changed
.
map
(
r
=>
r
.
uri
.
toString
()),
changedFolders
.
map
(
a
=>
a
.
toString
()));
});
});
test
(
'
reorder folders trigger change event
'
,
()
=>
{
const
target
=
sinon
.
spy
();
testObject
.
onDidChangeWorkspaceFolders
(
target
);
...
...
src/vs/workbench/services/workspace/node/workspaceEditingService.ts
浏览文件 @
e9650bd5
...
...
@@ -73,15 +73,28 @@ export class WorkspaceEditingService implements IWorkspaceEditingService {
}
// Add & Delete Folders
if
(
this
.
includesSingleFolderWorkspace
(
foldersToDelete
))
{
else
{
// if we are in single-folder state and the folder is replaced with
// other folders, we handle this specially and just enter workspace
// mode with the folders that are being added.
return
this
.
createAndEnterWorkspace
(
foldersToAdd
);
if
(
this
.
includesSingleFolderWorkspace
(
foldersToDelete
))
{
return
this
.
createAndEnterWorkspace
(
foldersToAdd
);
}
// if we are not in workspace-state, we just add the folders
if
(
this
.
contextService
.
getWorkbenchState
()
!==
WorkbenchState
.
WORKSPACE
)
{
return
this
.
doAddFolders
(
foldersToAdd
,
index
,
donotNotifyError
);
}
// finally, update folders within the workspace
return
this
.
doUpdateFolders
(
foldersToAdd
,
foldersToDelete
,
index
,
donotNotifyError
);
}
}
// Make sure to first remove folders and then add them to account for folders being updated
return
this
.
removeFolders
(
foldersToDelete
).
then
(()
=>
this
.
doAddFolders
(
foldersToAdd
,
index
,
donotNotifyError
));
private
doUpdateFolders
(
foldersToAdd
:
IWorkspaceFolderCreationData
[],
foldersToDelete
:
URI
[],
index
?:
number
,
donotNotifyError
:
boolean
=
false
):
TPromise
<
void
>
{
return
this
.
contextService
.
updateFolders
(
foldersToAdd
,
foldersToDelete
,
index
)
.
then
(()
=>
null
,
error
=>
donotNotifyError
?
TPromise
.
wrapError
(
error
)
:
this
.
handleWorkspaceConfigurationEditingError
(
error
));
}
public
addFolders
(
foldersToAdd
:
IWorkspaceFolderCreationData
[],
donotNotifyError
:
boolean
=
false
):
TPromise
<
void
>
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录