Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
a8842026
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,发现更多精彩内容 >>
提交
a8842026
编写于
7月 15, 2019
作者:
S
Sandeep Somavarapu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Adopt InMemoryUserDataProvider to use FileSystemProvider
上级
d5fcdf39
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
215 addition
and
111 deletion
+215
-111
src/vs/workbench/browser/web.main.ts
src/vs/workbench/browser/web.main.ts
+6
-3
src/vs/workbench/services/userData/common/inMemoryUserDataProvider.ts
...ench/services/userData/common/inMemoryUserDataProvider.ts
+209
-28
src/vs/workbench/services/userData/common/userData.ts
src/vs/workbench/services/userData/common/userData.ts
+0
-80
未找到文件。
src/vs/workbench/browser/web.main.ts
浏览文件 @
a8842026
...
...
@@ -42,6 +42,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage';
import
{
getThemeTypeSelector
,
DARK
,
HIGH_CONTRAST
,
LIGHT
}
from
'
vs/platform/theme/common/themeService
'
;
import
{
IRequestService
}
from
'
vs/platform/request/common/request
'
;
import
{
RequestService
}
from
'
vs/workbench/services/request/browser/requestService
'
;
import
{
InMemoryUserDataProvider
}
from
'
vs/workbench/services/userData/common/inMemoryUserDataProvider
'
;
class
CodeRendererMain
extends
Disposable
{
...
...
@@ -157,11 +158,13 @@ class CodeRendererMain extends Disposable {
}
}
// User Data Provider
if
(
userDataProvider
)
{
fileService
.
registerProvider
(
Schemas
.
userData
,
userDataProvider
);
if
(
!
userDataProvider
)
{
userDataProvider
=
this
.
_register
(
new
InMemoryUserDataProvider
());
}
// User Data Provider
fileService
.
registerProvider
(
Schemas
.
userData
,
userDataProvider
);
const
[
configurationService
,
storageService
]
=
await
Promise
.
all
([
this
.
createWorkspaceService
(
payload
,
environmentService
,
fileService
,
remoteAgentService
,
logService
).
then
(
service
=>
{
...
...
src/vs/workbench/services/userData/common/inMemoryUserDataProvider.ts
浏览文件 @
a8842026
...
...
@@ -4,48 +4,229 @@
*--------------------------------------------------------------------------------------------*/
import
{
Event
,
Emitter
}
from
'
vs/base/common/event
'
;
import
{
Disposable
,
to
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
IUserDataProvider
,
FileChangeEvent
}
from
'
vs/workbench/services/userData/common/userData
'
;
import
{
VSBuffer
}
from
'
vs/base/common/buffer
'
;
import
{
FileChangeType
}
from
'
vs/platform/files/common/files
'
;
import
{
Disposable
,
I
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
*
as
resources
from
'
vs/base/common/resources
'
;
import
{
FileChangeType
,
IFileSystemProvider
,
FileType
,
IWatchOptions
,
IStat
,
FileSystemProviderErrorCode
,
FileSystemProviderError
,
FileWriteOptions
,
IFileChange
,
FileDeleteOptions
,
FileSystemProviderCapabilities
,
FileOverwriteOptions
}
from
'
vs/platform/files/common/files
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
export
class
InMemoryUserDataProvider
extends
Disposable
implements
IUserDataProvider
{
_serviceBrand
:
any
;
class
File
implements
IStat
{
private
_onDidChangeFile
:
Emitter
<
FileChangeEvent
[]
>
=
this
.
_register
(
new
Emitter
<
FileChangeEvent
[]
>
());
readonly
onDidChangeFile
:
Event
<
FileChangeEvent
[]
>
=
this
.
_onDidChangeFile
.
event
;
type
:
FileType
;
ctime
:
number
;
mtime
:
number
;
size
:
number
;
private
readonly
store
:
Map
<
string
,
string
>
=
new
Map
<
string
,
string
>
();
name
:
string
;
data
?:
Uint8Array
;
constructor
()
{
super
();
this
.
_register
(
toDisposable
(()
=>
this
.
store
.
clear
()));
constructor
(
name
:
string
)
{
this
.
type
=
FileType
.
File
;
this
.
ctime
=
Date
.
now
();
this
.
mtime
=
Date
.
now
();
this
.
size
=
0
;
this
.
name
=
name
;
}
}
async
listFiles
(
path
:
string
):
Promise
<
string
[]
>
{
return
[];
class
Directory
implements
IStat
{
type
:
FileType
;
ctime
:
number
;
mtime
:
number
;
size
:
number
;
name
:
string
;
entries
:
Map
<
string
,
File
|
Directory
>
;
constructor
(
name
:
string
)
{
this
.
type
=
FileType
.
Directory
;
this
.
ctime
=
Date
.
now
();
this
.
mtime
=
Date
.
now
();
this
.
size
=
0
;
this
.
name
=
name
;
this
.
entries
=
new
Map
();
}
}
export
type
Entry
=
File
|
Directory
;
export
class
InMemoryUserDataProvider
extends
Disposable
implements
IFileSystemProvider
{
readonly
capabilities
:
FileSystemProviderCapabilities
=
FileSystemProviderCapabilities
.
FileReadWrite
;
readonly
onDidChangeCapabilities
:
Event
<
void
>
=
Event
.
None
;
root
=
new
Directory
(
''
);
// --- manage file metadata
async
stat
(
resource
:
URI
):
Promise
<
IStat
>
{
return
this
.
_lookup
(
resource
,
false
);
}
async
readdir
(
resource
:
URI
):
Promise
<
[
string
,
FileType
][]
>
{
const
entry
=
this
.
_lookupAsDirectory
(
resource
,
false
);
let
result
:
[
string
,
FileType
][]
=
[];
for
(
const
[
name
,
child
]
of
entry
.
entries
)
{
result
.
push
([
name
,
child
.
type
]);
}
return
result
;
}
// --- manage file contents
async
readFile
(
resource
:
URI
):
Promise
<
Uint8Array
>
{
const
data
=
this
.
_lookupAsFile
(
resource
,
false
).
data
;
if
(
data
)
{
return
data
;
}
throw
new
FileSystemProviderError
(
'
file not found
'
,
FileSystemProviderErrorCode
.
FileNotFound
);
}
async
writeFile
(
resource
:
URI
,
content
:
Uint8Array
,
opts
:
FileWriteOptions
):
Promise
<
void
>
{
let
basename
=
resources
.
basename
(
resource
);
let
parent
=
this
.
_lookupParentDirectory
(
resource
);
let
entry
=
parent
.
entries
.
get
(
basename
);
if
(
entry
instanceof
Directory
)
{
throw
new
FileSystemProviderError
(
'
file is directory
'
,
FileSystemProviderErrorCode
.
FileIsADirectory
);
}
if
(
!
entry
&&
!
opts
.
create
)
{
throw
new
FileSystemProviderError
(
'
file not found
'
,
FileSystemProviderErrorCode
.
FileNotFound
);
}
if
(
entry
&&
opts
.
create
&&
!
opts
.
overwrite
)
{
throw
new
FileSystemProviderError
(
'
file exists already
'
,
FileSystemProviderErrorCode
.
FileExists
);
}
if
(
!
entry
)
{
entry
=
new
File
(
basename
);
parent
.
entries
.
set
(
basename
,
entry
);
this
.
_fireSoon
({
type
:
FileChangeType
.
ADDED
,
resource
});
}
entry
.
mtime
=
Date
.
now
();
entry
.
size
=
content
.
byteLength
;
entry
.
data
=
content
;
this
.
_fireSoon
({
type
:
FileChangeType
.
UPDATED
,
resource
});
}
// --- manage files/folders
async
rename
(
from
:
URI
,
to
:
URI
,
opts
:
FileOverwriteOptions
):
Promise
<
void
>
{
if
(
!
opts
.
overwrite
&&
this
.
_lookup
(
to
,
true
))
{
throw
new
FileSystemProviderError
(
'
file exists already
'
,
FileSystemProviderErrorCode
.
FileExists
);
}
let
entry
=
this
.
_lookup
(
from
,
false
);
let
oldParent
=
this
.
_lookupParentDirectory
(
from
);
let
newParent
=
this
.
_lookupParentDirectory
(
to
);
let
newName
=
resources
.
basename
(
to
);
oldParent
.
entries
.
delete
(
entry
.
name
);
entry
.
name
=
newName
;
newParent
.
entries
.
set
(
newName
,
entry
);
this
.
_fireSoon
(
{
type
:
FileChangeType
.
DELETED
,
resource
:
from
},
{
type
:
FileChangeType
.
ADDED
,
resource
:
to
}
);
}
async
delete
(
resource
:
URI
,
opts
:
FileDeleteOptions
):
Promise
<
void
>
{
let
dirname
=
resources
.
dirname
(
resource
);
let
basename
=
resources
.
basename
(
resource
);
let
parent
=
this
.
_lookupAsDirectory
(
dirname
,
false
);
if
(
!
parent
.
entries
.
has
(
basename
))
{
throw
new
FileSystemProviderError
(
'
file not found
'
,
FileSystemProviderErrorCode
.
FileNotFound
);
}
parent
.
entries
.
delete
(
basename
);
parent
.
mtime
=
Date
.
now
();
parent
.
size
-=
1
;
this
.
_fireSoon
({
type
:
FileChangeType
.
UPDATED
,
resource
:
dirname
},
{
resource
,
type
:
FileChangeType
.
DELETED
});
}
async
mkdir
(
resource
:
URI
):
Promise
<
void
>
{
let
basename
=
resources
.
basename
(
resource
);
let
dirname
=
resources
.
dirname
(
resource
);
let
parent
=
this
.
_lookupAsDirectory
(
dirname
,
false
);
let
entry
=
new
Directory
(
basename
);
parent
.
entries
.
set
(
entry
.
name
,
entry
);
parent
.
mtime
=
Date
.
now
();
parent
.
size
+=
1
;
this
.
_fireSoon
({
type
:
FileChangeType
.
UPDATED
,
resource
:
dirname
},
{
type
:
FileChangeType
.
ADDED
,
resource
});
}
// --- lookup
private
_lookup
(
uri
:
URI
,
silent
:
false
):
Entry
;
private
_lookup
(
uri
:
URI
,
silent
:
boolean
):
Entry
|
undefined
;
private
_lookup
(
uri
:
URI
,
silent
:
boolean
):
Entry
|
undefined
{
let
parts
=
uri
.
path
.
split
(
'
/
'
);
let
entry
:
Entry
=
this
.
root
;
for
(
const
part
of
parts
)
{
if
(
!
part
)
{
continue
;
}
let
child
:
Entry
|
undefined
;
if
(
entry
instanceof
Directory
)
{
child
=
entry
.
entries
.
get
(
part
);
}
if
(
!
child
)
{
if
(
!
silent
)
{
throw
new
FileSystemProviderError
(
'
file not found
'
,
FileSystemProviderErrorCode
.
FileNotFound
);
}
else
{
return
undefined
;
}
}
entry
=
child
;
}
return
entry
;
}
async
readFile
(
path
:
string
):
Promise
<
Uint8Array
>
{
if
(
this
.
store
.
has
(
path
))
{
return
VSBuffer
.
fromString
(
this
.
store
.
get
(
path
)
!
).
buffer
;
private
_lookupAsDirectory
(
uri
:
URI
,
silent
:
boolean
):
Directory
{
let
entry
=
this
.
_lookup
(
uri
,
silent
);
if
(
entry
instanceof
Directory
)
{
return
entry
;
}
throw
new
Error
(
`Not Found:
${
path
}
`
);
throw
new
FileSystemProviderError
(
'
file not a directory
'
,
FileSystemProviderErrorCode
.
FileNotADirectory
);
}
async
writeFile
(
path
:
string
,
value
:
Uint8Array
):
Promise
<
void
>
{
const
exists
=
this
.
store
.
has
(
path
);
const
content
=
VSBuffer
.
wrap
(
value
).
toString
();
if
(
!
exists
||
content
!==
this
.
store
.
get
(
path
))
{
this
.
store
.
set
(
path
,
content
);
this
.
_onDidChangeFile
.
fire
([{
path
,
type
:
exists
?
FileChangeType
.
UPDATED
:
FileChangeType
.
ADDED
}]);
private
_lookupAsFile
(
uri
:
URI
,
silent
:
boolean
):
File
{
let
entry
=
this
.
_lookup
(
uri
,
silent
);
if
(
entry
instanceof
File
)
{
return
entry
;
}
throw
new
FileSystemProviderError
(
'
file is a directory
'
,
FileSystemProviderErrorCode
.
FileIsADirectory
);
}
async
deleteFile
(
path
:
string
):
Promise
<
void
>
{
if
(
this
.
store
.
has
(
path
))
{
this
.
store
.
delete
(
path
);
this
.
_onDidChangeFile
.
fire
([{
path
,
type
:
FileChangeType
.
DELETED
}]);
private
_lookupParentDirectory
(
uri
:
URI
):
Directory
{
const
dirname
=
resources
.
dirname
(
uri
);
return
this
.
_lookupAsDirectory
(
dirname
,
false
);
}
// --- manage file events
private
readonly
_onDidChangeFile
:
Emitter
<
IFileChange
[]
>
=
this
.
_register
(
new
Emitter
<
IFileChange
[]
>
());
readonly
onDidChangeFile
:
Event
<
IFileChange
[]
>
=
this
.
_onDidChangeFile
.
event
;
private
_bufferedChanges
:
IFileChange
[]
=
[];
private
_fireSoonHandle
?:
NodeJS
.
Timer
;
watch
(
resource
:
URI
,
opts
:
IWatchOptions
):
IDisposable
{
// ignore, fires for all changes...
return
Disposable
.
None
;
}
private
_fireSoon
(...
changes
:
IFileChange
[]):
void
{
this
.
_bufferedChanges
.
push
(...
changes
);
if
(
this
.
_fireSoonHandle
)
{
clearTimeout
(
this
.
_fireSoonHandle
);
}
this
.
_fireSoonHandle
=
setTimeout
(()
=>
{
this
.
_onDidChangeFile
.
fire
(
this
.
_bufferedChanges
);
this
.
_bufferedChanges
.
length
=
0
;
},
5
);
}
}
\ No newline at end of file
src/vs/workbench/services/userData/common/userData.ts
已删除
100644 → 0
浏览文件 @
d5fcdf39
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
Event
}
from
'
vs/base/common/event
'
;
import
{
FileChangeType
}
from
'
vs/platform/files/common/files
'
;
/**
* The event user data providers must use to signal a file change.
*/
export
interface
FileChangeEvent
{
/**
* The type of change.
*/
readonly
type
:
FileChangeType
;
/**
* The path of the file that has changed.
*/
readonly
path
:
string
;
}
/**
* The userDataProvider is used to handle user specific application
* state like settings, keybindings, UI state (e.g. opened editors) and snippets.
*
* The API reflects a simple file system provider that comes with the notion of paths
* (UNIX slash separated) as well as files. Folders are not a top level concept (e.g. we
* do not require to create or delete them), however, files can be grouped beneath one path
* and also listed from that path.
*
* Example:
* ```ts
* await writeFile('snippets/global/markdown.json', <some data>);
* await writeFile('snippets/global/html.json', <some data>);
* await writeFile('snippets/global/javascript.json', <some data>);
*
* const files = await listFiles('snippets/global');
* console.log(files); // -> ['snippets/global/markdown.json', 'snippets/global/html.json', 'snippets/global/javascript.json']
* ```
*/
export
interface
IUserDataProvider
{
/**
* An event to signal that a file has been created, changed, or deleted.
*/
readonly
onDidChangeFile
:
Event
<
FileChangeEvent
[]
>
;
/**
* Read the file contents of the given path.
*
* Throw an error if the path does not exist.
*/
readFile
(
path
:
string
):
Promise
<
Uint8Array
>
;
/**
* Writes the provided content to the file path overwriting any existing content on that path.
*
* If the path does not exist, it will be created.
*
* Throw an error if the path is a parent to existing files.
*/
writeFile
(
path
:
string
,
content
:
Uint8Array
):
Promise
<
void
>
;
/**
* Delete the file at the given path.
*
* Does NOT throw an error when the path does not exist.
*/
deleteFile
(
path
:
string
):
Promise
<
void
>
;
/**
* Returns an array of files at the given path.
*
* Throw an error if the path does not exist or points to a file.
*/
listFiles
(
path
:
string
):
Promise
<
string
[]
>
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录