Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
49852131
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 搜索 >>
提交
49852131
编写于
7月 04, 2019
作者:
S
Sandeep Somavarapu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
make user data provider a full fledged filesystem provider
上级
60dcb1ac
变更
11
展开全部
隐藏空白更改
内联
并排
Showing
11 changed file
with
178 addition
and
898 deletion
+178
-898
src/vs/workbench/browser/web.main.ts
src/vs/workbench/browser/web.main.ts
+13
-21
src/vs/workbench/contrib/snippets/browser/snippets.contribution.ts
...rkbench/contrib/snippets/browser/snippets.contribution.ts
+0
-3
src/vs/workbench/electron-browser/main.ts
src/vs/workbench/electron-browser/main.ts
+3
-3
src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts
...test/electron-browser/configurationEditingService.test.ts
+15
-4
src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts
...ration/test/electron-browser/configurationService.test.ts
+35
-21
src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts
...eybinding/test/electron-browser/keybindingEditing.test.ts
+15
-4
src/vs/workbench/services/userData/common/fileUserDataProvider.ts
...orkbench/services/userData/common/fileUserDataProvider.ts
+94
-80
src/vs/workbench/services/userData/common/userData.ts
src/vs/workbench/services/userData/common/userData.ts
+1
-59
src/vs/workbench/services/userData/common/userDataFileSystemProvider.ts
...ch/services/userData/common/userDataFileSystemProvider.ts
+0
-156
src/vs/workbench/services/userData/test/electron-browser/fileUserDataProvider.test.ts
...erData/test/electron-browser/fileUserDataProvider.test.ts
+0
-545
src/vs/workbench/workbench.web.api.ts
src/vs/workbench/workbench.web.api.ts
+2
-2
未找到文件。
src/vs/workbench/browser/web.main.ts
浏览文件 @
49852131
...
...
@@ -19,7 +19,7 @@ import { RemoteAgentService } from 'vs/workbench/services/remote/browser/remoteA
import
{
RemoteAuthorityResolverService
}
from
'
vs/platform/remote/browser/remoteAuthorityResolverService
'
;
import
{
IRemoteAuthorityResolverService
}
from
'
vs/platform/remote/common/remoteAuthorityResolver
'
;
import
{
IRemoteAgentService
}
from
'
vs/workbench/services/remote/common/remoteAgentService
'
;
import
{
IFileService
}
from
'
vs/platform/files/common/files
'
;
import
{
IFileService
,
IFileSystemProvider
}
from
'
vs/platform/files/common/files
'
;
import
{
FileService
}
from
'
vs/workbench/services/files/common/fileService
'
;
import
{
Schemas
}
from
'
vs/base/common/network
'
;
import
{
IWorkspaceContextService
}
from
'
vs/platform/workspace/common/workspace
'
;
...
...
@@ -35,10 +35,7 @@ import { hash } from 'vs/base/common/hash';
import
{
IWorkbenchConstructionOptions
}
from
'
vs/workbench/workbench.web.api
'
;
import
{
ProductService
}
from
'
vs/platform/product/browser/productService
'
;
import
{
FileUserDataProvider
}
from
'
vs/workbench/services/userData/common/fileUserDataProvider
'
;
import
{
UserDataFileSystemProvider
}
from
'
vs/workbench/services/userData/common/userDataFileSystemProvider
'
;
import
{
joinPath
}
from
'
vs/base/common/resources
'
;
import
{
InMemoryUserDataProvider
}
from
'
vs/workbench/services/userData/common/inMemoryUserDataProvider
'
;
import
{
IUserDataProvider
}
from
'
vs/workbench/services/userData/common/userData
'
;
import
{
joinPath
,
dirname
}
from
'
vs/base/common/resources
'
;
class
CodeRendererMain
extends
Disposable
{
...
...
@@ -110,16 +107,26 @@ class CodeRendererMain extends Disposable {
const
fileService
=
this
.
_register
(
new
FileService
(
logService
));
serviceCollection
.
set
(
IFileService
,
fileService
);
let
userDataProvider
:
IFileSystemProvider
|
undefined
=
this
.
configuration
.
userDataProvider
;
const
connection
=
remoteAgentService
.
getConnection
();
if
(
connection
)
{
const
channel
=
connection
.
getChannel
<
IChannel
>
(
REMOTE_FILE_SYSTEM_CHANNEL_NAME
);
const
remoteFileSystemProvider
=
this
.
_register
(
new
RemoteExtensionsFileSystemProvider
(
channel
,
remoteAgentService
.
getEnvironment
()));
fileService
.
registerProvider
(
Schemas
.
vscodeRemote
,
remoteFileSystemProvider
);
if
(
!
userDataProvider
)
{
const
remoteUserDataUri
=
this
.
getRemoteUserDataUri
();
if
(
remoteUserDataUri
)
{
userDataProvider
=
this
.
_register
(
new
FileUserDataProvider
(
remoteUserDataUri
,
dirname
(
remoteUserDataUri
),
remoteFileSystemProvider
));
}
}
}
// User Data Provider
fileService
.
registerProvider
(
Schemas
.
userData
,
new
UserDataFileSystemProvider
(
environmentService
.
userRoamingDataHome
,
this
.
getUserDataPovider
(
fileService
)));
if
(
userDataProvider
)
{
fileService
.
registerProvider
(
Schemas
.
userData
,
userDataProvider
);
}
const
payload
=
await
this
.
resolveWorkspaceInitializationPayload
();
...
...
@@ -169,21 +176,6 @@ class CodeRendererMain extends Disposable {
return
{
id
:
'
empty-window
'
};
}
private
getUserDataPovider
(
fileService
:
IFileService
):
IUserDataProvider
{
if
(
this
.
configuration
.
userDataProvider
)
{
return
this
.
configuration
.
userDataProvider
;
}
if
(
this
.
configuration
.
remoteAuthority
)
{
const
remoteUserDataUri
=
this
.
getRemoteUserDataUri
();
if
(
remoteUserDataUri
)
{
return
this
.
_register
(
new
FileUserDataProvider
(
remoteUserDataUri
,
fileService
));
}
}
return
this
.
_register
(
new
InMemoryUserDataProvider
());
}
private
getRemoteUserDataUri
():
URI
|
null
{
const
element
=
document
.
getElementById
(
'
vscode-remote-user-data-uri
'
);
if
(
element
)
{
...
...
src/vs/workbench/contrib/snippets/browser/snippets.contribution.ts
浏览文件 @
49852131
...
...
@@ -10,12 +10,9 @@ import * as nls from 'vs/nls';
import
{
createDecorator
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
LanguageId
}
from
'
vs/editor/common/modes
'
;
import
{
SnippetFile
,
Snippet
}
from
'
vs/workbench/contrib/snippets/browser/snippetsFile
'
;
import
{
IUserDataContainerRegistry
,
Extensions
}
from
'
vs/workbench/services/userData/common/userData
'
;
export
const
ISnippetsService
=
createDecorator
<
ISnippetsService
>
(
'
snippetService
'
);
Registry
.
as
<
IUserDataContainerRegistry
>
(
Extensions
.
UserDataContainers
).
registerContainer
(
'
snippets
'
);
export
interface
ISnippetsService
{
_serviceBrand
:
any
;
...
...
src/vs/workbench/electron-browser/main.ts
浏览文件 @
49852131
...
...
@@ -51,7 +51,6 @@ import { SpdLogService } from 'vs/platform/log/node/spdlogService';
import
{
SignService
}
from
'
vs/platform/sign/node/signService
'
;
import
{
ISignService
}
from
'
vs/platform/sign/common/sign
'
;
import
{
FileUserDataProvider
}
from
'
vs/workbench/services/userData/common/fileUserDataProvider
'
;
import
{
UserDataFileSystemProvider
}
from
'
vs/workbench/services/userData/common/userDataFileSystemProvider
'
;
class
CodeRendererMain
extends
Disposable
{
...
...
@@ -200,6 +199,9 @@ class CodeRendererMain extends Disposable {
const
diskFileSystemProvider
=
this
.
_register
(
new
DiskFileSystemProvider
(
logService
));
fileService
.
registerProvider
(
Schemas
.
file
,
diskFileSystemProvider
);
// User Data Provider
fileService
.
registerProvider
(
Schemas
.
userData
,
new
FileUserDataProvider
(
environmentService
.
appSettingsHome
,
URI
.
file
(
environmentService
.
backupHome
),
diskFileSystemProvider
));
const
connection
=
remoteAgentService
.
getConnection
();
if
(
connection
)
{
const
channel
=
connection
.
getChannel
<
IChannel
>
(
REMOTE_FILE_SYSTEM_CHANNEL_NAME
);
...
...
@@ -207,8 +209,6 @@ class CodeRendererMain extends Disposable {
fileService
.
registerProvider
(
Schemas
.
vscodeRemote
,
remoteFileSystemProvider
);
}
// User Data Provider
fileService
.
registerProvider
(
Schemas
.
userData
,
new
UserDataFileSystemProvider
(
environmentService
.
userRoamingDataHome
,
new
FileUserDataProvider
(
environmentService
.
appSettingsHome
,
fileService
)));
const
payload
=
await
this
.
resolveWorkspaceInitializationPayload
(
environmentService
);
...
...
src/vs/workbench/services/configuration/test/electron-browser/configurationEditingService.test.ts
浏览文件 @
49852131
...
...
@@ -39,10 +39,20 @@ import { DiskFileSystemProvider } from 'vs/workbench/services/files/node/diskFil
import
{
IFileService
}
from
'
vs/platform/files/common/files
'
;
import
{
ConfigurationCache
}
from
'
vs/workbench/services/configuration/node/configurationCache
'
;
import
{
KeybindingsEditingService
,
IKeybindingEditingService
}
from
'
vs/workbench/services/keybinding/common/keybindingEditing
'
;
import
{
UserDataFileSystemProvider
}
from
'
vs/workbench/services/userData/common/userDataFileSystemProvider
'
;
import
{
WorkbenchEnvironmentService
}
from
'
vs/workbench/services/environment/node/environmentService
'
;
import
{
IWindowConfiguration
}
from
'
vs/platform/windows/common/windows
'
;
import
{
FileUserDataProvider
}
from
'
vs/workbench/services/userData/common/fileUserDataProvider
'
;
import
{
dirname
}
from
'
vs/base/common/resources
'
;
class
TestBackupEnvironmentService
extends
WorkbenchEnvironmentService
{
constructor
(
private
_appSettingsHome
:
URI
)
{
super
(
parseArgs
(
process
.
argv
)
as
IWindowConfiguration
,
process
.
execPath
);
}
get
appSettingsHome
()
{
return
this
.
_appSettingsHome
;
}
}
suite
(
'
ConfigurationEditingService
'
,
()
=>
{
...
...
@@ -95,14 +105,15 @@ suite('ConfigurationEditingService', () => {
clearServices
();
instantiationService
=
<
TestInstantiationService
>
workbenchInstantiationService
();
const
environmentService
=
new
WorkbenchEnvironmentService
(
<
IWindowConfiguration
>
parseArgs
(
process
.
argv
),
process
.
execPath
);
const
environmentService
=
new
TestBackupEnvironmentService
(
URI
.
file
(
workspaceDir
)
);
instantiationService
.
stub
(
IEnvironmentService
,
environmentService
);
const
remoteAgentService
=
instantiationService
.
createInstance
(
RemoteAgentService
,
{});
const
fileService
=
new
FileService
(
new
NullLogService
());
fileService
.
registerProvider
(
Schemas
.
file
,
new
DiskFileSystemProvider
(
new
NullLogService
()));
const
diskFileSystemProvider
=
new
DiskFileSystemProvider
(
new
NullLogService
());
fileService
.
registerProvider
(
Schemas
.
file
,
diskFileSystemProvider
);
fileService
.
registerProvider
(
Schemas
.
userData
,
new
FileUserDataProvider
(
URI
.
file
(
workspaceDir
),
dirname
(
URI
.
file
(
workspaceDir
)),
diskFileSystemProvider
));
instantiationService
.
stub
(
IFileService
,
fileService
);
instantiationService
.
stub
(
IRemoteAgentService
,
remoteAgentService
);
fileService
.
registerProvider
(
Schemas
.
userData
,
new
UserDataFileSystemProvider
(
environmentService
.
userRoamingDataHome
,
new
FileUserDataProvider
(
URI
.
file
(
workspaceDir
),
fileService
)));
const
workspaceService
=
new
WorkspaceService
({
configurationCache
:
new
ConfigurationCache
(
environmentService
)
},
environmentService
,
fileService
,
remoteAgentService
);
instantiationService
.
stub
(
IWorkspaceContextService
,
workspaceService
);
return
workspaceService
.
initialize
(
noWorkspace
?
{
id
:
''
}
:
{
folder
:
URI
.
file
(
workspaceDir
),
id
:
createHash
(
'
md5
'
).
update
(
URI
.
file
(
workspaceDir
).
toString
()).
digest
(
'
hex
'
)
}).
then
(()
=>
{
...
...
src/vs/workbench/services/configuration/test/electron-browser/configurationService.test.ts
浏览文件 @
49852131
...
...
@@ -30,7 +30,7 @@ import { IJSONEditingService } from 'vs/workbench/services/configuration/common/
import
{
JSONEditingService
}
from
'
vs/workbench/services/configuration/common/jsonEditingService
'
;
import
{
createHash
}
from
'
crypto
'
;
import
{
Schemas
}
from
'
vs/base/common/network
'
;
import
{
originalFSPath
}
from
'
vs/base/common/resources
'
;
import
{
originalFSPath
,
dirname
}
from
'
vs/base/common/resources
'
;
import
{
isLinux
}
from
'
vs/base/common/platform
'
;
import
{
IWindowConfiguration
}
from
'
vs/platform/windows/common/windows
'
;
import
{
RemoteAgentService
}
from
'
vs/workbench/services/remote/electron-browser/remoteAgentServiceImpl
'
;
...
...
@@ -47,9 +47,18 @@ import { SignService } from 'vs/platform/sign/browser/signService';
import
{
FileUserDataProvider
}
from
'
vs/workbench/services/userData/common/fileUserDataProvider
'
;
import
{
IKeybindingEditingService
,
KeybindingsEditingService
}
from
'
vs/workbench/services/keybinding/common/keybindingEditing
'
;
import
{
WorkbenchEnvironmentService
}
from
'
vs/workbench/services/environment/node/environmentService
'
;
import
{
UserDataFileSystemProvider
}
from
'
vs/workbench/services/userData/common/userDataFileSystemProvider
'
;
import
{
IWorkbenchEnvironmentService
}
from
'
vs/workbench/services/environment/common/environmentService
'
;
class
TestEnvironmentService
extends
WorkbenchEnvironmentService
{
constructor
(
private
_appSettingsHome
:
URI
)
{
super
(
parseArgs
(
process
.
argv
)
as
IWindowConfiguration
,
process
.
execPath
);
}
get
appSettingsHome
()
{
return
this
.
_appSettingsHome
;
}
}
function
setUpFolderWorkspace
(
folderName
:
string
):
Promise
<
{
parentDir
:
string
,
folderDir
:
string
}
>
{
const
id
=
uuid
.
generateUuid
();
const
parentDir
=
path
.
join
(
os
.
tmpdir
(),
'
vsctests
'
,
id
);
...
...
@@ -96,9 +105,9 @@ suite('WorkspaceContextService - Folder', () => {
.
then
(({
parentDir
,
folderDir
})
=>
{
parentResource
=
parentDir
;
workspaceResource
=
folderDir
;
const
environmentService
=
new
WorkbenchEnvironmentService
(
<
IWindowConfiguration
>
parseArgs
(
process
.
argv
),
process
.
execPath
);
const
environmentService
=
new
TestEnvironmentService
(
URI
.
file
(
parentDir
)
);
const
fileService
=
new
FileService
(
new
NullLogService
());
fileService
.
registerProvider
(
Schemas
.
userData
,
new
UserDataFileSystemProvider
(
environmentService
.
userRoamingDataHome
,
new
FileUserDataProvider
(
URI
.
file
(
parentDir
),
fileService
)));
fileService
.
registerProvider
(
Schemas
.
userData
,
new
FileUserDataProvider
(
environmentService
.
appSettingsHome
,
dirname
(
environmentService
.
appSettingsHome
),
new
DiskFileSystemProvider
(
new
NullLogService
()
)));
workspaceContextService
=
new
WorkspaceService
({
configurationCache
:
new
ConfigurationCache
(
environmentService
)
},
environmentService
,
fileService
,
new
RemoteAgentService
(
<
IWindowConfiguration
>
{},
environmentService
,
new
RemoteAuthorityResolverService
(),
new
SignService
()));
return
(
<
WorkspaceService
>
workspaceContextService
).
initialize
(
convertToWorkspacePayload
(
URI
.
file
(
folderDir
)));
});
...
...
@@ -158,12 +167,13 @@ suite('WorkspaceContextService - Workspace', () => {
parentResource
=
parentDir
;
instantiationService
=
<
TestInstantiationService
>
workbenchInstantiationService
();
const
environmentService
=
new
WorkbenchEnvironmentService
(
<
IWindowConfiguration
>
parseArgs
(
process
.
argv
),
process
.
execPath
);
const
environmentService
=
new
TestEnvironmentService
(
URI
.
file
(
parentDir
)
);
const
remoteAgentService
=
instantiationService
.
createInstance
(
RemoteAgentService
,
{});
instantiationService
.
stub
(
IRemoteAgentService
,
remoteAgentService
);
const
fileService
=
new
FileService
(
new
NullLogService
());
fileService
.
registerProvider
(
Schemas
.
file
,
new
DiskFileSystemProvider
(
new
NullLogService
()));
fileService
.
registerProvider
(
Schemas
.
userData
,
new
UserDataFileSystemProvider
(
environmentService
.
userRoamingDataHome
,
new
FileUserDataProvider
(
URI
.
file
(
parentDir
),
fileService
)));
const
diskFileSystemProvider
=
new
DiskFileSystemProvider
(
new
NullLogService
());
fileService
.
registerProvider
(
Schemas
.
file
,
diskFileSystemProvider
);
fileService
.
registerProvider
(
Schemas
.
userData
,
new
FileUserDataProvider
(
environmentService
.
appSettingsHome
,
dirname
(
environmentService
.
appSettingsHome
),
diskFileSystemProvider
));
const
workspaceService
=
new
WorkspaceService
({
configurationCache
:
new
ConfigurationCache
(
environmentService
)
},
environmentService
,
fileService
,
remoteAgentService
);
instantiationService
.
stub
(
IWorkspaceContextService
,
workspaceService
);
...
...
@@ -217,12 +227,13 @@ suite('WorkspaceContextService - Workspace Editing', () => {
parentResource
=
parentDir
;
instantiationService
=
<
TestInstantiationService
>
workbenchInstantiationService
();
const
environmentService
=
new
WorkbenchEnvironmentService
(
<
IWindowConfiguration
>
parseArgs
(
process
.
argv
),
process
.
execPath
);
const
environmentService
=
new
TestEnvironmentService
(
URI
.
file
(
parentDir
)
);
const
remoteAgentService
=
instantiationService
.
createInstance
(
RemoteAgentService
,
{});
instantiationService
.
stub
(
IRemoteAgentService
,
remoteAgentService
);
const
fileService
=
new
FileService
(
new
NullLogService
());
fileService
.
registerProvider
(
Schemas
.
file
,
new
DiskFileSystemProvider
(
new
NullLogService
()));
fileService
.
registerProvider
(
Schemas
.
userData
,
new
UserDataFileSystemProvider
(
environmentService
.
userRoamingDataHome
,
new
FileUserDataProvider
(
URI
.
file
(
parentDir
),
fileService
)));
const
diskFileSystemProvider
=
new
DiskFileSystemProvider
(
new
NullLogService
());
fileService
.
registerProvider
(
Schemas
.
file
,
diskFileSystemProvider
);
fileService
.
registerProvider
(
Schemas
.
userData
,
new
FileUserDataProvider
(
environmentService
.
appSettingsHome
,
dirname
(
environmentService
.
appSettingsHome
),
diskFileSystemProvider
));
const
workspaceService
=
new
WorkspaceService
({
configurationCache
:
new
ConfigurationCache
(
environmentService
)
},
environmentService
,
fileService
,
remoteAgentService
);
instantiationService
.
stub
(
IWorkspaceContextService
,
workspaceService
);
...
...
@@ -477,12 +488,13 @@ suite('WorkspaceService - Initialization', () => {
globalSettingsFile
=
path
.
join
(
parentDir
,
'
settings.json
'
);
const
instantiationService
=
<
TestInstantiationService
>
workbenchInstantiationService
();
const
environmentService
=
new
WorkbenchEnvironmentService
(
<
IWindowConfiguration
>
parseArgs
(
process
.
argv
),
process
.
execPath
);
const
environmentService
=
new
TestEnvironmentService
(
URI
.
file
(
parentDir
)
);
const
remoteAgentService
=
instantiationService
.
createInstance
(
RemoteAgentService
,
{});
instantiationService
.
stub
(
IRemoteAgentService
,
remoteAgentService
);
const
fileService
=
new
FileService
(
new
NullLogService
());
fileService
.
registerProvider
(
Schemas
.
file
,
new
DiskFileSystemProvider
(
new
NullLogService
()));
fileService
.
registerProvider
(
Schemas
.
userData
,
new
UserDataFileSystemProvider
(
environmentService
.
userRoamingDataHome
,
new
FileUserDataProvider
(
URI
.
file
(
parentDir
),
fileService
)));
const
diskFileSystemProvider
=
new
DiskFileSystemProvider
(
new
NullLogService
());
fileService
.
registerProvider
(
Schemas
.
file
,
diskFileSystemProvider
);
fileService
.
registerProvider
(
Schemas
.
userData
,
new
FileUserDataProvider
(
environmentService
.
appSettingsHome
,
dirname
(
environmentService
.
appSettingsHome
),
diskFileSystemProvider
));
const
workspaceService
=
new
WorkspaceService
({
configurationCache
:
new
ConfigurationCache
(
environmentService
)
},
environmentService
,
fileService
,
remoteAgentService
);
instantiationService
.
stub
(
IWorkspaceContextService
,
workspaceService
);
instantiationService
.
stub
(
IConfigurationService
,
workspaceService
);
...
...
@@ -740,12 +752,13 @@ suite('WorkspaceConfigurationService - Folder', () => {
globalSettingsFile
=
path
.
join
(
parentDir
,
'
settings.json
'
);
const
instantiationService
=
<
TestInstantiationService
>
workbenchInstantiationService
();
const
environmentService
=
new
WorkbenchEnvironmentService
(
<
IWindowConfiguration
>
parseArgs
(
process
.
argv
),
process
.
execPath
);
const
environmentService
=
new
TestEnvironmentService
(
URI
.
file
(
parentDir
)
);
const
remoteAgentService
=
instantiationService
.
createInstance
(
RemoteAgentService
,
{});
instantiationService
.
stub
(
IRemoteAgentService
,
remoteAgentService
);
const
fileService
=
new
FileService
(
new
NullLogService
());
fileService
.
registerProvider
(
Schemas
.
file
,
new
DiskFileSystemProvider
(
new
NullLogService
()));
fileService
.
registerProvider
(
Schemas
.
userData
,
new
UserDataFileSystemProvider
(
environmentService
.
userRoamingDataHome
,
new
FileUserDataProvider
(
URI
.
file
(
parentDir
),
fileService
)));
const
diskFileSystemProvider
=
new
DiskFileSystemProvider
(
new
NullLogService
());
fileService
.
registerProvider
(
Schemas
.
file
,
diskFileSystemProvider
);
fileService
.
registerProvider
(
Schemas
.
userData
,
new
FileUserDataProvider
(
environmentService
.
appSettingsHome
,
dirname
(
environmentService
.
appSettingsHome
),
diskFileSystemProvider
));
const
workspaceService
=
new
WorkspaceService
({
configurationCache
:
new
ConfigurationCache
(
environmentService
)
},
environmentService
,
fileService
,
remoteAgentService
);
instantiationService
.
stub
(
IWorkspaceContextService
,
workspaceService
);
instantiationService
.
stub
(
IConfigurationService
,
workspaceService
);
...
...
@@ -1069,12 +1082,13 @@ suite('WorkspaceConfigurationService-Multiroot', () => {
globalSettingsFile
=
path
.
join
(
parentDir
,
'
settings.json
'
);
const
instantiationService
=
<
TestInstantiationService
>
workbenchInstantiationService
();
const
environmentService
=
new
WorkbenchEnvironmentService
(
<
IWindowConfiguration
>
parseArgs
(
process
.
argv
),
process
.
execPath
);
const
environmentService
=
new
TestEnvironmentService
(
URI
.
file
(
parentDir
)
);
const
remoteAgentService
=
instantiationService
.
createInstance
(
RemoteAgentService
,
{});
instantiationService
.
stub
(
IRemoteAgentService
,
remoteAgentService
);
const
fileService
=
new
FileService
(
new
NullLogService
());
fileService
.
registerProvider
(
Schemas
.
file
,
new
DiskFileSystemProvider
(
new
NullLogService
()));
fileService
.
registerProvider
(
Schemas
.
userData
,
new
UserDataFileSystemProvider
(
environmentService
.
userRoamingDataHome
,
new
FileUserDataProvider
(
URI
.
file
(
parentDir
),
fileService
)));
const
diskFileSystemProvider
=
new
DiskFileSystemProvider
(
new
NullLogService
());
fileService
.
registerProvider
(
Schemas
.
file
,
diskFileSystemProvider
);
fileService
.
registerProvider
(
Schemas
.
userData
,
new
FileUserDataProvider
(
environmentService
.
appSettingsHome
,
dirname
(
environmentService
.
appSettingsHome
),
diskFileSystemProvider
));
const
workspaceService
=
new
WorkspaceService
({
configurationCache
:
new
ConfigurationCache
(
environmentService
)
},
environmentService
,
fileService
,
remoteAgentService
);
instantiationService
.
stub
(
IWorkspaceContextService
,
workspaceService
);
...
...
@@ -1471,12 +1485,12 @@ suite('WorkspaceConfigurationService - Remote Folder', () => {
remoteSettingsFile
=
path
.
join
(
parentDir
,
'
remote-settings.json
'
);
instantiationService
=
<
TestInstantiationService
>
workbenchInstantiationService
();
const
environmentService
=
new
WorkbenchEnvironmentService
(
<
IWindowConfiguration
>
parseArgs
(
process
.
argv
),
process
.
execPath
);
const
environmentService
=
new
TestEnvironmentService
(
URI
.
file
(
parentDir
)
);
const
remoteEnvironmentPromise
=
new
Promise
<
Partial
<
IRemoteAgentEnvironment
>>
(
c
=>
resolveRemoteEnvironment
=
()
=>
c
({
settingsPath
:
URI
.
file
(
remoteSettingsFile
).
with
({
scheme
:
Schemas
.
vscodeRemote
,
authority
:
remoteAuthority
})
}));
const
remoteAgentService
=
instantiationService
.
stub
(
IRemoteAgentService
,
<
Partial
<
IRemoteAgentService
>>
{
getEnvironment
:
()
=>
remoteEnvironmentPromise
});
const
fileService
=
new
FileService
(
new
NullLogService
());
fileService
.
registerProvider
(
Schemas
.
file
,
diskFileSystemProvider
);
fileService
.
registerProvider
(
Schemas
.
userData
,
new
UserDataFileSystemProvider
(
environmentService
.
userRoamingDataHome
,
new
FileUserDataProvider
(
URI
.
file
(
parentDir
),
fileService
)
));
fileService
.
registerProvider
(
Schemas
.
userData
,
new
FileUserDataProvider
(
environmentService
.
appSettingsHome
,
dirname
(
environmentService
.
appSettingsHome
),
diskFileSystemProvider
));
const
configurationCache
:
IConfigurationCache
=
{
read
:
()
=>
Promise
.
resolve
(
''
),
write
:
()
=>
Promise
.
resolve
(),
remove
:
()
=>
Promise
.
resolve
()
};
testObject
=
new
WorkspaceService
({
configurationCache
,
remoteAuthority
},
environmentService
,
fileService
,
remoteAgentService
);
instantiationService
.
stub
(
IWorkspaceContextService
,
testObject
);
...
...
src/vs/workbench/services/keybinding/test/electron-browser/keybindingEditing.test.ts
浏览文件 @
49852131
...
...
@@ -45,11 +45,21 @@ import { FileService } from 'vs/workbench/services/files/common/fileService';
import
{
Schemas
}
from
'
vs/base/common/network
'
;
import
{
DiskFileSystemProvider
}
from
'
vs/workbench/services/files/node/diskFileSystemProvider
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
UserDataFileSystemProvider
}
from
'
vs/workbench/services/userData/common/userDataFileSystemProvider
'
;
import
{
FileUserDataProvider
}
from
'
vs/workbench/services/userData/common/fileUserDataProvider
'
;
import
{
parseArgs
}
from
'
vs/platform/environment/node/argv
'
;
import
{
WorkbenchEnvironmentService
}
from
'
vs/workbench/services/environment/node/environmentService
'
;
import
{
IWindowConfiguration
}
from
'
vs/platform/windows/common/windows
'
;
import
{
dirname
}
from
'
vs/base/common/resources
'
;
class
TestBackupEnvironmentService
extends
WorkbenchEnvironmentService
{
constructor
(
private
_appSettingsHome
:
URI
)
{
super
(
parseArgs
(
process
.
argv
)
as
IWindowConfiguration
,
process
.
execPath
);
}
get
appSettingsHome
()
{
return
this
.
_appSettingsHome
;
}
}
interface
Modifiers
{
metaKey
?:
boolean
;
...
...
@@ -71,7 +81,7 @@ suite('KeybindingsEditing', () => {
instantiationService
=
new
TestInstantiationService
();
const
environmentService
=
new
WorkbenchEnvironmentService
(
<
IWindowConfiguration
>
parseArgs
(
process
.
argv
),
process
.
execPath
);
const
environmentService
=
new
TestBackupEnvironmentService
(
URI
.
file
(
testDir
)
);
instantiationService
.
stub
(
IEnvironmentService
,
environmentService
);
instantiationService
.
stub
(
IConfigurationService
,
ConfigurationService
);
instantiationService
.
stub
(
IConfigurationService
,
'
getValue
'
,
{
'
eol
'
:
'
\n
'
});
...
...
@@ -89,8 +99,9 @@ suite('KeybindingsEditing', () => {
instantiationService
.
stub
(
ITextResourcePropertiesService
,
new
TestTextResourcePropertiesService
(
instantiationService
.
get
(
IConfigurationService
)));
instantiationService
.
stub
(
IModelService
,
instantiationService
.
createInstance
(
ModelServiceImpl
));
const
fileService
=
new
FileService
(
new
NullLogService
());
fileService
.
registerProvider
(
Schemas
.
file
,
new
DiskFileSystemProvider
(
new
NullLogService
()));
fileService
.
registerProvider
(
Schemas
.
userData
,
new
UserDataFileSystemProvider
(
environmentService
.
userRoamingDataHome
,
new
FileUserDataProvider
(
URI
.
file
(
testDir
),
fileService
)));
const
diskFileSystemProvider
=
new
DiskFileSystemProvider
(
new
NullLogService
());
fileService
.
registerProvider
(
Schemas
.
file
,
diskFileSystemProvider
);
fileService
.
registerProvider
(
Schemas
.
userData
,
new
FileUserDataProvider
(
environmentService
.
appSettingsHome
,
dirname
(
environmentService
.
appSettingsHome
),
diskFileSystemProvider
));
instantiationService
.
stub
(
IFileService
,
fileService
);
instantiationService
.
stub
(
IUntitledEditorService
,
instantiationService
.
createInstance
(
UntitledEditorService
));
instantiationService
.
stub
(
ITextFileService
,
instantiationService
.
createInstance
(
TestTextFileService
));
...
...
src/vs/workbench/services/userData/common/fileUserDataProvider.ts
浏览文件 @
49852131
...
...
@@ -4,120 +4,134 @@
*--------------------------------------------------------------------------------------------*/
import
{
Event
,
Emitter
}
from
'
vs/base/common/event
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
IUserDataProvider
,
FileChangeEvent
,
IUserDataContainerRegistry
,
Extensions
}
from
'
vs/workbench/services/userData/common/userData
'
;
import
{
IFileService
,
FileChangesEvent
,
FileChangeType
}
from
'
vs/platform/files/common/files
'
;
import
{
Disposable
,
IDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
IFileSystemProviderWithFileReadWriteCapability
,
IFileChange
,
IWatchOptions
,
IStat
,
FileOverwriteOptions
,
FileType
,
FileWriteOptions
,
FileDeleteOptions
,
FileSystemProviderCapabilities
,
IFileSystemProviderWithOpenReadWriteCloseCapability
,
FileOpenOptions
,
hasReadWriteCapability
,
hasOpenReadWriteCloseCapability
}
from
'
vs/platform/files/common/files
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
*
as
resources
from
'
vs/base/common/resources
'
;
import
{
VSBuffer
}
from
'
vs/base/common/buffer
'
;
import
{
startsWith
}
from
'
vs/base/common/strings
'
;
import
{
BACKUPS
}
from
'
vs/platform/environment/common/environment
'
;
import
{
Registry
}
from
'
vs/platform/registry/common/platform
'
;
import
{
Schemas
}
from
'
vs/base/common/network
'
;
export
class
FileUserDataProvider
extends
Disposable
implements
I
UserDataProvider
{
export
class
FileUserDataProvider
extends
Disposable
implements
I
FileSystemProviderWithFileReadWriteCapability
,
IFileSystemProviderWithOpenReadWriteCloseCapability
{
private
_onDidChangeFile
:
Emitter
<
FileChangeEvent
[]
>
=
this
.
_register
(
new
Emitter
<
FileChangeEvent
[]
>
());
readonly
onDidChangeFile
:
Event
<
FileChangeEvent
[]
>
=
this
.
_onDidChangeFile
.
event
;
readonly
capabilities
:
FileSystemProviderCapabilities
=
this
.
fileSystemProvider
.
capabilities
;
readonly
onDidChangeCapabilities
:
Event
<
void
>
=
Event
.
None
;
private
readonly
_onDidChangeFile
:
Emitter
<
IFileChange
[]
>
=
this
.
_register
(
new
Emitter
<
IFileChange
[]
>
());
readonly
onDidChangeFile
:
Event
<
IFileChange
[]
>
=
this
.
_onDidChangeFile
.
event
;
constructor
(
private
readonly
userDataHome
:
URI
,
@
IFileService
private
readonly
fileService
:
IFileService
private
readonly
backupsHome
:
URI
,
private
readonly
fileSystemProvider
:
IFileSystemProviderWithFileReadWriteCapability
|
IFileSystemProviderWithOpenReadWriteCloseCapability
,
)
{
super
();
// Assumption: This path always exists
this
.
_register
(
this
.
fileService
.
watch
(
this
.
userDataHome
));
this
.
_register
(
this
.
fileService
.
onFileChanges
(
e
=>
this
.
handleFileChanges
(
e
)));
const
userDataContainersRegistry
=
Registry
.
as
<
IUserDataContainerRegistry
>
(
Extensions
.
UserDataContainers
);
userDataContainersRegistry
.
containers
.
forEach
(
c
=>
this
.
watchContainer
(
c
));
this
.
_register
(
userDataContainersRegistry
.
onDidRegisterContainer
(
c
=>
this
.
watchContainer
(
c
)));
}
private
handleFileChanges
(
event
:
FileChangesEvent
):
void
{
const
changedPaths
:
FileChangeEvent
[]
=
[];
const
userDataContainersRegistry
=
Registry
.
as
<
IUserDataContainerRegistry
>
(
Extensions
.
UserDataContainers
);
for
(
const
change
of
event
.
changes
)
{
if
(
change
.
resource
.
scheme
===
this
.
userDataHome
.
scheme
)
{
const
path
=
this
.
toPath
(
change
.
resource
);
if
(
path
)
{
changedPaths
.
push
({
path
,
type
:
change
.
type
});
if
(
userDataContainersRegistry
.
isContainer
(
path
))
{
if
(
change
.
type
===
FileChangeType
.
ADDED
)
{
this
.
watchContainer
(
path
);
}
}
}
}
}
if
(
changedPaths
.
length
)
{
this
.
_onDidChangeFile
.
fire
(
changedPaths
);
this
.
_register
(
this
.
fileSystemProvider
.
watch
(
this
.
userDataHome
,
{
recursive
:
false
,
excludes
:
[]
}));
this
.
_register
(
this
.
fileSystemProvider
.
onDidChangeFile
(
e
=>
this
.
handleFileChanges
(
e
)));
}
watch
(
resource
:
URI
,
opts
:
IWatchOptions
):
IDisposable
{
return
this
.
fileSystemProvider
.
watch
(
this
.
toFileSystemResource
(
resource
),
opts
);
}
stat
(
resource
:
URI
):
Promise
<
IStat
>
{
return
this
.
fileSystemProvider
.
stat
(
this
.
toFileSystemResource
(
resource
));
}
mkdir
(
resource
:
URI
):
Promise
<
void
>
{
return
this
.
fileSystemProvider
.
mkdir
(
this
.
toFileSystemResource
(
resource
));
}
rename
(
from
:
URI
,
to
:
URI
,
opts
:
FileOverwriteOptions
):
Promise
<
void
>
{
return
this
.
fileSystemProvider
.
rename
(
this
.
toFileSystemResource
(
from
),
this
.
toFileSystemResource
(
to
),
opts
);
}
readFile
(
resource
:
URI
):
Promise
<
Uint8Array
>
{
if
(
hasReadWriteCapability
(
this
.
fileSystemProvider
))
{
return
this
.
fileSystemProvider
.
readFile
(
this
.
toFileSystemResource
(
resource
));
}
throw
new
Error
(
'
not supported
'
);
}
readdir
(
resource
:
URI
):
Promise
<
[
string
,
FileType
][]
>
{
return
this
.
fileSystemProvider
.
readdir
(
this
.
toFileSystemResource
(
resource
));
}
private
async
watchContainer
(
container
:
string
):
Promise
<
void
>
{
if
(
this
.
isBackUpsPath
(
contain
er
))
{
return
;
writeFile
(
resource
:
URI
,
content
:
Uint8Array
,
opts
:
FileWriteOptions
):
Promise
<
void
>
{
if
(
hasReadWriteCapability
(
this
.
fileSystemProvid
er
))
{
return
this
.
fileSystemProvider
.
writeFile
(
this
.
toFileSystemResource
(
resource
),
content
,
opts
)
;
}
const
resource
=
this
.
toResource
(
container
);
const
exists
=
await
this
.
fileService
.
exists
(
resource
);
if
(
exists
)
{
this
.
_register
(
this
.
fileService
.
watch
(
resource
));
throw
new
Error
(
'
not supported
'
);
}
open
(
resource
:
URI
,
opts
:
FileOpenOptions
):
Promise
<
number
>
{
if
(
hasOpenReadWriteCloseCapability
(
this
.
fileSystemProvider
))
{
return
this
.
fileSystemProvider
.
open
(
this
.
toFileSystemResource
(
resource
),
opts
);
}
throw
new
Error
(
'
not supported
'
);
}
async
readFile
(
path
:
string
):
Promise
<
Uint8Array
>
{
const
resource
=
this
.
toResource
(
path
);
const
content
=
await
this
.
fileService
.
readFile
(
resource
);
return
content
.
value
.
buffer
;
close
(
fd
:
number
):
Promise
<
void
>
{
if
(
hasOpenReadWriteCloseCapability
(
this
.
fileSystemProvider
))
{
return
this
.
fileSystemProvider
.
close
(
fd
);
}
throw
new
Error
(
'
not supported
'
);
}
writeFile
(
path
:
string
,
value
:
Uint8Array
):
Promise
<
void
>
{
return
this
.
fileService
.
writeFile
(
this
.
toResource
(
path
),
VSBuffer
.
wrap
(
value
)).
then
(()
=>
undefined
);
read
(
fd
:
number
,
pos
:
number
,
data
:
Uint8Array
,
offset
:
number
,
length
:
number
):
Promise
<
number
>
{
if
(
hasOpenReadWriteCloseCapability
(
this
.
fileSystemProvider
))
{
return
this
.
fileSystemProvider
.
read
(
fd
,
pos
,
data
,
offset
,
length
);
}
throw
new
Error
(
'
not supported
'
);
}
async
listFiles
(
path
:
string
):
Promise
<
string
[]
>
{
const
resource
=
this
.
toResource
(
path
);
try
{
const
result
=
await
this
.
fileService
.
resolve
(
resource
);
if
(
result
.
children
)
{
return
result
.
children
.
filter
(
c
=>
!
c
.
isDirectory
)
.
map
(
c
=>
this
.
toRelativePath
(
c
.
resource
,
resource
)
!
);
}
}
catch
(
error
)
{
write
(
fd
:
number
,
pos
:
number
,
data
:
Uint8Array
,
offset
:
number
,
length
:
number
):
Promise
<
number
>
{
if
(
hasOpenReadWriteCloseCapability
(
this
.
fileSystemProvider
))
{
return
this
.
fileSystemProvider
.
write
(
fd
,
pos
,
data
,
offset
,
length
);
}
return
[]
;
throw
new
Error
(
'
not supported
'
)
;
}
delete
File
(
path
:
string
):
Promise
<
void
>
{
return
this
.
fileS
ervice
.
del
(
this
.
toResource
(
path
)
);
delete
(
resource
:
URI
,
opts
:
FileDeleteOptions
):
Promise
<
void
>
{
return
this
.
fileS
ystemProvider
.
delete
(
this
.
toFileSystemResource
(
resource
),
opts
);
}
private
toResource
(
path
:
string
):
URI
{
if
(
this
.
isBackUpsPath
(
path
))
{
return
resources
.
joinPath
(
resources
.
dirname
(
this
.
userDataHome
),
path
);
private
handleFileChanges
(
changes
:
IFileChange
[]):
void
{
const
userDataChanges
:
IFileChange
[]
=
[];
for
(
const
change
of
changes
)
{
const
userDataResource
=
this
.
toUserDataResource
(
change
.
resource
);
if
(
userDataResource
)
{
userDataChanges
.
push
({
resource
:
userDataResource
,
type
:
change
.
type
});
}
}
if
(
userDataChanges
.
length
)
{
this
.
_onDidChangeFile
.
fire
(
userDataChanges
);
}
return
resources
.
joinPath
(
this
.
userDataHome
,
path
);
}
private
isBackUpsPath
(
path
:
string
):
boolean
{
return
path
===
BACKUPS
||
startsWith
(
path
,
`
${
BACKUPS
}
/`
);
private
toFileSystemResource
(
userDataResource
:
URI
):
URI
{
const
fileSystemResource
=
userDataResource
.
with
({
scheme
:
this
.
userDataHome
.
scheme
});
const
relativePath
=
resources
.
relativePath
(
this
.
userDataHome
,
fileSystemResource
);
if
(
relativePath
&&
startsWith
(
relativePath
,
BACKUPS
))
{
return
resources
.
joinPath
(
resources
.
dirname
(
this
.
backupsHome
),
relativePath
);
}
return
fileSystemResource
;
}
private
toPath
(
resource
:
URI
):
string
|
undefined
{
let
result
=
this
.
toRelativePath
(
resource
,
this
.
userDataHome
);
if
(
result
===
undefined
)
{
result
=
this
.
toRelativePath
(
resource
,
resources
.
joinPath
(
resources
.
dirname
(
this
.
userDataHome
),
BACKUPS
));
private
toUserDataResource
(
fileSystemResource
:
URI
):
URI
|
null
{
if
(
resources
.
relativePath
(
this
.
userDataHome
,
fileSystemResource
))
{
return
fileSystemResource
.
with
({
scheme
:
Schemas
.
userData
});
}
const
relativePath
=
resources
.
relativePath
(
this
.
backupsHome
,
fileSystemResource
);
if
(
relativePath
)
{
return
resources
.
joinPath
(
this
.
userDataHome
,
BACKUPS
,
relativePath
).
with
({
scheme
:
Schemas
.
userData
});
}
return
result
;
return
null
;
}
private
toRelativePath
(
fromResource
:
URI
,
toResource
:
URI
):
string
|
undefined
{
const
fromPath
=
fromResource
.
toString
();
const
toPath
=
toResource
.
toString
();
return
startsWith
(
fromPath
,
toPath
)
?
fromPath
.
substr
(
toPath
.
length
+
1
)
:
undefined
;
}
}
\ No newline at end of file
src/vs/workbench/services/userData/common/userData.ts
浏览文件 @
49852131
...
...
@@ -3,9 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
Event
,
Emitter
}
from
'
vs/base/common/event
'
;
import
{
TernarySearchTree
}
from
'
vs/base/common/map
'
;
import
{
Registry
}
from
'
vs/platform/registry/common/platform
'
;
import
{
Event
}
from
'
vs/base/common/event
'
;
import
{
FileChangeType
}
from
'
vs/platform/files/common/files
'
;
/**
...
...
@@ -80,59 +78,3 @@ export interface IUserDataProvider {
*/
listFiles
(
path
:
string
):
Promise
<
string
[]
>
;
}
export
interface
IUserDataContainerRegistry
{
/**
* An event to signal that a container has been registered.
*/
readonly
onDidRegisterContainer
:
Event
<
string
>
;
/**
* Registered containers
*/
readonly
containers
:
string
[];
/**
* Register the given path as an user data container if user data files are stored under this path.
*
* It is required to register the container to access the user data files under the container.
*/
registerContainer
(
path
:
string
):
void
;
/**
* Returns true if the given path is an user data container or sub container of user data container
*/
isContainer
(
path
:
string
):
boolean
;
}
class
UserDataContainerRegistry
implements
IUserDataContainerRegistry
{
private
_containers
:
TernarySearchTree
<
string
>
=
TernarySearchTree
.
forStrings
();
private
_onDidRegisterContainer
:
Emitter
<
string
>
=
new
Emitter
<
string
>
();
readonly
onDidRegisterContainer
:
Event
<
string
>
=
this
.
_onDidRegisterContainer
.
event
;
get
containers
():
string
[]
{
const
containers
:
string
[]
=
[];
this
.
_containers
.
forEach
(
c
=>
containers
.
push
(
c
));
return
containers
;
}
public
registerContainer
(
path
:
string
):
void
{
if
(
!
this
.
_containers
.
get
(
path
))
{
this
.
_containers
.
set
(
path
,
path
);
this
.
_onDidRegisterContainer
.
fire
(
path
);
}
}
isContainer
(
path
:
string
):
boolean
{
return
!!
this
.
_containers
.
get
(
path
)
||
!!
this
.
_containers
.
findSuperstr
(
path
);
}
}
export
const
Extensions
=
{
UserDataContainers
:
'
workbench.contributions.userDataContainers
'
};
Registry
.
add
(
Extensions
.
UserDataContainers
,
new
UserDataContainerRegistry
());
\ No newline at end of file
src/vs/workbench/services/userData/common/userDataFileSystemProvider.ts
已删除
100644 → 0
浏览文件 @
60dcb1ac
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
IDisposable
,
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
FileSystemProviderCapabilities
,
FileWriteOptions
,
IStat
,
FileType
,
FileDeleteOptions
,
IWatchOptions
,
FileOverwriteOptions
,
IFileSystemProviderWithFileReadWriteCapability
,
IFileChange
,
FileChangeType
,
FileChangesEvent
}
from
'
vs/platform/files/common/files
'
;
import
{
IUserDataProvider
,
IUserDataContainerRegistry
,
Extensions
,
FileChangeEvent
}
from
'
vs/workbench/services/userData/common/userData
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
Event
,
Emitter
}
from
'
vs/base/common/event
'
;
import
{
startsWith
}
from
'
vs/base/common/strings
'
;
import
{
Registry
}
from
'
vs/platform/registry/common/platform
'
;
import
{
joinPath
}
from
'
vs/base/common/resources
'
;
export
class
UserDataFileSystemProvider
extends
Disposable
implements
IFileSystemProviderWithFileReadWriteCapability
{
private
readonly
versions
:
Map
<
string
,
number
>
=
new
Map
<
string
,
number
>
();
readonly
capabilities
:
FileSystemProviderCapabilities
=
FileSystemProviderCapabilities
.
FileReadWrite
;
readonly
onDidChangeCapabilities
:
Event
<
void
>
=
Event
.
None
;
private
readonly
_onDidChangeFile
:
Emitter
<
IFileChange
[]
>
=
this
.
_register
(
new
Emitter
<
IFileChange
[]
>
());
readonly
onDidChangeFile
:
Event
<
IFileChange
[]
>
=
this
.
_onDidChangeFile
.
event
;
constructor
(
private
readonly
userDataHome
:
URI
,
private
readonly
userDataProvider
:
IUserDataProvider
)
{
super
();
this
.
_register
(
this
.
userDataProvider
.
onDidChangeFile
(
changes
=>
this
.
onDidChangeUserData
(
changes
)));
}
private
onDidChangeUserData
(
changes
:
FileChangeEvent
[]):
void
{
const
fileChanges
:
IFileChange
[]
=
[];
for
(
const
{
path
,
type
}
of
changes
)
{
if
(
type
===
FileChangeType
.
DELETED
)
{
this
.
versions
.
delete
(
path
);
}
else
{
this
.
versions
.
set
(
path
,
this
.
getOrSetVersion
(
path
)
+
1
);
}
fileChanges
.
push
({
resource
:
this
.
toResource
(
path
),
type
});
}
if
(
fileChanges
.
length
)
{
this
.
_onDidChangeFile
.
fire
(
new
FileChangesEvent
(
fileChanges
).
changes
);
}
}
watch
(
resource
:
URI
,
opts
:
IWatchOptions
):
IDisposable
{
const
path
=
this
.
toPath
(
resource
);
if
(
!
path
)
{
throw
new
Error
(
`Invalid user data resource
${
resource
}
`
);
}
return
Disposable
.
None
;
}
async
stat
(
resource
:
URI
):
Promise
<
IStat
>
{
const
path
=
this
.
toPath
(
resource
);
if
(
path
===
undefined
)
{
throw
new
Error
(
`Invalid user data resource
${
resource
}
`
);
}
if
(
this
.
isContainer
(
path
))
{
return
{
type
:
FileType
.
Directory
,
ctime
:
0
,
mtime
:
this
.
getOrSetVersion
(
path
),
size
:
0
};
}
const
result
=
await
this
.
readFile
(
resource
);
return
{
type
:
FileType
.
File
,
ctime
:
0
,
mtime
:
this
.
getOrSetVersion
(
path
),
size
:
result
.
byteLength
};
}
mkdir
(
resource
:
URI
):
Promise
<
void
>
{
throw
new
Error
(
'
not supported
'
);
}
rename
(
from
:
URI
,
to
:
URI
,
opts
:
FileOverwriteOptions
):
Promise
<
void
>
{
throw
new
Error
(
'
not supported
'
);
}
async
readFile
(
resource
:
URI
):
Promise
<
Uint8Array
>
{
const
path
=
this
.
toPath
(
resource
);
if
(
!
path
)
{
throw
new
Error
(
`Invalid user data resource
${
resource
}
`
);
}
if
(
this
.
isContainer
(
path
))
{
throw
new
Error
(
`Invalid user data file
${
resource
}
`
);
}
return
this
.
userDataProvider
.
readFile
(
path
);
}
async
readdir
(
resource
:
URI
):
Promise
<
[
string
,
FileType
][]
>
{
const
path
=
this
.
toPath
(
resource
);
if
(
!
path
)
{
throw
new
Error
(
`Invalid user data resource
${
resource
}
`
);
}
if
(
!
this
.
isContainer
(
path
))
{
throw
new
Error
(
`Invalid user data container
${
resource
}
`
);
}
const
children
=
await
this
.
userDataProvider
.
listFiles
(
path
);
return
children
.
map
(
c
=>
[
c
,
FileType
.
File
]);
}
writeFile
(
resource
:
URI
,
content
:
Uint8Array
,
opts
:
FileWriteOptions
):
Promise
<
void
>
{
const
path
=
this
.
toPath
(
resource
);
if
(
!
path
)
{
throw
new
Error
(
`Invalid user data resource
${
resource
}
`
);
}
if
(
this
.
isContainer
(
path
))
{
throw
new
Error
(
`Invalid user data file
${
resource
}
`
);
}
return
this
.
userDataProvider
.
writeFile
(
path
,
content
);
}
delete
(
resource
:
URI
,
opts
:
FileDeleteOptions
):
Promise
<
void
>
{
const
path
=
this
.
toPath
(
resource
);
if
(
!
path
)
{
throw
new
Error
(
`Invalid user data resource
${
resource
}
`
);
}
if
(
this
.
isContainer
(
path
))
{
throw
new
Error
(
`Invalid user data file
${
resource
}
`
);
}
return
this
.
userDataProvider
.
deleteFile
(
path
);
}
private
getOrSetVersion
(
path
:
string
):
number
{
if
(
!
this
.
versions
.
has
(
path
))
{
this
.
versions
.
set
(
path
,
1
);
}
return
this
.
versions
.
get
(
path
)
!
;
}
private
isContainer
(
path
:
string
):
boolean
{
if
(
path
===
''
)
{
return
true
;
// Root
}
return
Registry
.
as
<
IUserDataContainerRegistry
>
(
Extensions
.
UserDataContainers
).
isContainer
(
path
);
}
private
toResource
(
path
:
string
):
URI
{
return
joinPath
(
this
.
userDataHome
,
path
);
}
private
toPath
(
resource
:
URI
):
string
|
undefined
{
return
this
.
toRelativePath
(
resource
,
this
.
userDataHome
);
}
private
toRelativePath
(
fromResource
:
URI
,
toResource
:
URI
):
string
|
undefined
{
const
fromPath
=
fromResource
.
toString
();
const
toPath
=
toResource
.
toString
();
return
startsWith
(
fromPath
,
toPath
)
?
fromPath
.
substr
(
toPath
.
length
+
1
)
:
undefined
;
}
}
\ No newline at end of file
src/vs/workbench/services/userData/test/electron-browser/fileUserDataProvider.test.ts
已删除
100644 → 0
浏览文件 @
60dcb1ac
此差异已折叠。
点击以展开。
src/vs/workbench/workbench.web.api.ts
浏览文件 @
49852131
...
...
@@ -6,7 +6,7 @@
import
'
vs/workbench/workbench.web.main
'
;
import
{
main
}
from
'
vs/workbench/browser/web.main
'
;
import
{
UriComponents
}
from
'
vs/base/common/uri
'
;
import
{
I
UserDataProvider
}
from
'
vs/workbench/services/userData/common/userData
'
;
import
{
I
FileSystemProviderWithFileReadWriteCapability
,
IFileSystemProviderWithOpenReadWriteCloseCapability
}
from
'
vs/platform/files/common/files
'
;
export
interface
IWorkbenchConstructionOptions
{
...
...
@@ -36,7 +36,7 @@ export interface IWorkbenchConstructionOptions {
* Experimental: The userDataProvider is used to handle user specific application
* state like settings, keybindings, UI state (e.g. opened editors) and snippets.
*/
userDataProvider
?:
I
UserDataProvider
;
userDataProvider
?:
I
FileSystemProviderWithFileReadWriteCapability
|
IFileSystemProviderWithOpenReadWriteCloseCapability
;
}
/**
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录