Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
5da116f3
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,发现更多精彩内容 >>
提交
5da116f3
编写于
2月 20, 2020
作者:
B
Benjamin Pasero
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
editors - track out of workspace watchers in editor service
上级
884c2d28
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
106 addition
and
105 deletion
+106
-105
src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts
...kbench/contrib/files/browser/editors/fileEditorTracker.ts
+24
-80
src/vs/workbench/services/editor/browser/editorService.ts
src/vs/workbench/services/editor/browser/editorService.ts
+82
-25
未找到文件。
src/vs/workbench/contrib/files/browser/editors/fileEditorTracker.ts
浏览文件 @
5da116f3
...
...
@@ -6,15 +6,12 @@
import
{
IWorkbenchContribution
}
from
'
vs/workbench/common/contributions
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
IEditorViewState
}
from
'
vs/editor/common/editorCommon
'
;
import
{
toResource
,
SideBySideEditor
as
SideBySideEditorChoice
}
from
'
vs/workbench/common/editor
'
;
import
{
ITextFileService
,
TextFileEditorModelState
}
from
'
vs/workbench/services/textfile/common/textfiles
'
;
import
{
FileOperationEvent
,
FileOperation
,
IFileService
,
FileSystemProviderCapabilities
}
from
'
vs/platform/files/common/files
'
;
import
{
FileEditorInput
}
from
'
vs/workbench/contrib/files/common/editors/fileEditorInput
'
;
import
{
ILifecycleService
}
from
'
vs/platform/lifecycle/common/lifecycle
'
;
import
{
Disposable
,
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
distinct
,
coalesce
}
from
'
vs/base/common/arrays
'
;
import
{
ResourceMap
}
from
'
vs/base/common/map
'
;
import
{
IWorkspaceContextService
}
from
'
vs/platform/workspace/common/workspace
'
;
import
{
isCodeEditor
}
from
'
vs/editor/browser/editorBrowser
'
;
import
{
IHostService
}
from
'
vs/workbench/services/host/browser/host
'
;
import
{
IEditorService
}
from
'
vs/workbench/services/editor/common/editorService
'
;
...
...
@@ -27,15 +24,12 @@ import { Schemas } from 'vs/base/common/network';
export
class
FileEditorTracker
extends
Disposable
implements
IWorkbenchContribution
{
private
readonly
activeOutOfWorkspaceWatchers
=
new
ResourceMap
<
IDisposable
>
();
constructor
(
@
IEditorService
private
readonly
editorService
:
IEditorService
,
@
ITextFileService
private
readonly
textFileService
:
ITextFileService
,
@
ILifecycleService
private
readonly
lifecycleService
:
ILifecycleService
,
@
IEditorGroupsService
private
readonly
editorGroupService
:
IEditorGroupsService
,
@
IFileService
private
readonly
fileService
:
IFileService
,
@
IWorkspaceContextService
private
readonly
contextService
:
IWorkspaceContextService
,
@
IHostService
private
readonly
hostService
:
IHostService
,
@
ICodeEditorService
private
readonly
codeEditorService
:
ICodeEditorService
)
{
...
...
@@ -54,11 +48,8 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut
this
.
_register
(
this
.
textFileService
.
files
.
onDidSaveError
(
model
=>
this
.
ensureDirtyFilesAreOpenedWorker
.
work
(
model
.
resource
)));
this
.
_register
(
this
.
textFileService
.
untitled
.
onDidChangeDirty
(
model
=>
this
.
ensureDirtyFilesAreOpenedWorker
.
work
(
model
.
resource
)));
// Out of workspace file watchers
this
.
_register
(
this
.
editorService
.
onDidVisibleEditorsChange
(()
=>
this
.
onDidVisibleEditorsChange
()));
// Update visible editors when focus is gained
this
.
_register
(
this
.
hostService
.
onDidChangeFocus
(
e
=>
this
.
onWindowFocusChange
(
e
)
));
this
.
_register
(
this
.
hostService
.
onDidChangeFocus
(
hasFocus
=>
hasFocus
?
this
.
reloadVisibleTextFileEditors
()
:
undefined
));
// Lifecycle
this
.
lifecycleService
.
onShutdown
(
this
.
dispose
,
this
);
...
...
@@ -163,7 +154,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut
private
readonly
ensureDirtyFilesAreOpenedWorker
=
this
.
_register
(
new
RunOnceWorker
<
URI
>
(
units
=>
this
.
ensureDirtyTextFilesAreOpened
(
units
),
250
));
private
ensureDirtyTextFilesAreOpened
(
resources
:
URI
[]):
void
{
this
.
doEnsureDirtyFilesAreOpened
(
distinct
(
resources
.
filter
(
resource
=>
{
this
.
doEnsureDirty
Text
FilesAreOpened
(
distinct
(
resources
.
filter
(
resource
=>
{
if
(
!
this
.
textFileService
.
isDirty
(
resource
))
{
return
false
;
// resource must be dirty
}
...
...
@@ -181,7 +172,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut
}),
resource
=>
resource
.
toString
()));
}
private
doEnsureDirtyFilesAreOpened
(
resources
:
URI
[]):
void
{
private
doEnsureDirty
Text
FilesAreOpened
(
resources
:
URI
[]):
void
{
if
(
!
resources
.
length
)
{
return
;
}
...
...
@@ -194,78 +185,31 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut
//#endregion
//#region Visible Editors Change: Install file watchers for out of workspace resources that became visible
private
onDidVisibleEditorsChange
():
void
{
const
visibleOutOfWorkspaceResources
=
new
ResourceMap
<
URI
>
();
for
(
const
editor
of
this
.
editorService
.
visibleEditors
)
{
const
resources
=
distinct
(
coalesce
([
toResource
(
editor
,
{
supportSideBySide
:
SideBySideEditorChoice
.
MASTER
}),
toResource
(
editor
,
{
supportSideBySide
:
SideBySideEditorChoice
.
DETAILS
})
]),
resource
=>
resource
.
toString
());
for
(
const
resource
of
resources
)
{
if
(
this
.
fileService
.
canHandleResource
(
resource
)
&&
!
this
.
contextService
.
isInsideWorkspace
(
resource
))
{
visibleOutOfWorkspaceResources
.
set
(
resource
,
resource
);
}
}
}
// Handle no longer visible out of workspace resources
this
.
activeOutOfWorkspaceWatchers
.
keys
().
forEach
(
resource
=>
{
if
(
!
visibleOutOfWorkspaceResources
.
get
(
resource
))
{
dispose
(
this
.
activeOutOfWorkspaceWatchers
.
get
(
resource
));
this
.
activeOutOfWorkspaceWatchers
.
delete
(
resource
);
}
});
// Handle newly visible out of workspace resources
visibleOutOfWorkspaceResources
.
forEach
(
resource
=>
{
if
(
!
this
.
activeOutOfWorkspaceWatchers
.
get
(
resource
))
{
const
disposable
=
this
.
fileService
.
watch
(
resource
);
this
.
activeOutOfWorkspaceWatchers
.
set
(
resource
,
disposable
);
}
});
}
//#endregion
//#region Window Focus Change: Update visible code editors when focus is gained that have a known text file model
private
onWindowFocusChange
(
focused
:
boolean
):
void
{
if
(
focused
)
{
// the window got focus and we use this as a hint that files might have been changed outside
// of this window. since file events can be unreliable, we queue a load for models that
// are visible in any editor. since this is a fast operation in the case nothing has changed,
// we tolerate the additional work.
distinct
(
coalesce
(
this
.
codeEditorService
.
listCodeEditors
()
.
map
(
codeEditor
=>
{
const
resource
=
codeEditor
.
getModel
()?.
uri
;
if
(
!
resource
)
{
return
undefined
;
}
private
reloadVisibleTextFileEditors
():
void
{
// the window got focus and we use this as a hint that files might have been changed outside
// of this window. since file events can be unreliable, we queue a load for models that
// are visible in any editor. since this is a fast operation in the case nothing has changed,
// we tolerate the additional work.
distinct
(
coalesce
(
this
.
codeEditorService
.
listCodeEditors
()
.
map
(
codeEditor
=>
{
const
resource
=
codeEditor
.
getModel
()?.
uri
;
if
(
!
resource
)
{
return
undefined
;
}
const
model
=
this
.
textFileService
.
files
.
get
(
resource
);
if
(
!
model
||
model
.
isDirty
()
||
!
model
.
isResolved
())
{
return
undefined
;
}
const
model
=
this
.
textFileService
.
files
.
get
(
resource
);
if
(
!
model
||
model
.
isDirty
()
||
!
model
.
isResolved
())
{
return
undefined
;
}
return
model
;
})),
model
=>
model
.
resource
.
toString
()
).
forEach
(
model
=>
this
.
textFileService
.
files
.
resolve
(
model
.
resource
,
{
reload
:
{
async
:
true
}
}));
}
return
model
;
})),
model
=>
model
.
resource
.
toString
()
).
forEach
(
model
=>
this
.
textFileService
.
files
.
resolve
(
model
.
resource
,
{
reload
:
{
async
:
true
}
}));
}
//#endregion
dispose
():
void
{
super
.
dispose
();
// Dispose remaining watchers if any
this
.
activeOutOfWorkspaceWatchers
.
forEach
(
disposable
=>
dispose
(
disposable
));
this
.
activeOutOfWorkspaceWatchers
.
clear
();
}
}
src/vs/workbench/services/editor/browser/editorService.ts
浏览文件 @
5da116f3
...
...
@@ -5,7 +5,7 @@
import
{
IInstantiationService
,
ServicesAccessor
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IResourceInput
,
ITextEditorOptions
,
IEditorOptions
,
EditorActivation
}
from
'
vs/platform/editor/common/editor
'
;
import
{
IEditorInput
,
IEditor
,
GroupIdentifier
,
IFileEditorInput
,
IUntitledTextResourceInput
,
IResourceDiffInput
,
IResourceSideBySideInput
,
IEditorInputFactoryRegistry
,
Extensions
as
EditorExtensions
,
IFileInputFactory
,
EditorInput
,
SideBySideEditorInput
,
IEditorInputWithOptions
,
isEditorInputWithOptions
,
EditorOptions
,
TextEditorOptions
,
IEditorIdentifier
,
IEditorCloseEvent
,
ITextEditor
,
ITextDiffEditor
,
ITextSideBySideEditor
,
IRevertOptions
,
SaveReason
,
EditorsOrder
,
isTextEditor
,
IWorkbenchEditorConfiguration
}
from
'
vs/workbench/common/editor
'
;
import
{
SideBySideEditor
as
SideBySideEditorChoice
,
IEditorInput
,
IEditor
,
GroupIdentifier
,
IFileEditorInput
,
IUntitledTextResourceInput
,
IResourceDiffInput
,
IResourceSideBySideInput
,
IEditorInputFactoryRegistry
,
Extensions
as
EditorExtensions
,
EditorInput
,
SideBySideEditorInput
,
IEditorInputWithOptions
,
isEditorInputWithOptions
,
EditorOptions
,
TextEditorOptions
,
IEditorIdentifier
,
IEditorCloseEvent
,
ITextEditor
,
ITextDiffEditor
,
ITextSideBySideEditor
,
IRevertOptions
,
SaveReason
,
EditorsOrder
,
isTextEditor
,
IWorkbenchEditorConfiguration
,
toResource
}
from
'
vs/workbench/common/editor
'
;
import
{
ResourceEditorInput
}
from
'
vs/workbench/common/editor/resourceEditorInput
'
;
import
{
Registry
}
from
'
vs/platform/registry/common/platform
'
;
import
{
ResourceMap
}
from
'
vs/base/common/map
'
;
...
...
@@ -20,7 +20,7 @@ import { IEditorGroupsService, IEditorGroup, GroupsOrder, IEditorReplacement, Gr
import
{
IResourceEditor
,
SIDE_GROUP
,
IResourceEditorReplacement
,
IOpenEditorOverrideHandler
,
IVisibleEditor
,
IEditorService
,
SIDE_GROUP_TYPE
,
ACTIVE_GROUP_TYPE
,
ISaveEditorsOptions
,
ISaveAllEditorsOptions
,
IRevertAllEditorsOptions
,
IBaseSaveRevertAllEditorOptions
}
from
'
vs/workbench/services/editor/common/editorService
'
;
import
{
IConfigurationService
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
Disposable
,
IDisposable
,
dispose
,
toDisposable
,
DisposableStore
}
from
'
vs/base/common/lifecycle
'
;
import
{
coalesce
}
from
'
vs/base/common/arrays
'
;
import
{
coalesce
,
distinct
}
from
'
vs/base/common/arrays
'
;
import
{
isCodeEditor
,
isDiffEditor
,
ICodeEditor
,
IDiffEditor
}
from
'
vs/editor/browser/editorBrowser
'
;
import
{
IEditorGroupView
,
IEditorOpeningEvent
,
EditorServiceImpl
}
from
'
vs/workbench/browser/parts/editor/editor
'
;
import
{
ILabelService
}
from
'
vs/platform/label/common/label
'
;
...
...
@@ -32,6 +32,7 @@ import { IUntitledTextEditorModel } from 'vs/workbench/services/untitled/common/
import
{
UntitledTextEditorInput
}
from
'
vs/workbench/services/untitled/common/untitledTextEditorInput
'
;
import
{
IEnvironmentService
}
from
'
vs/platform/environment/common/environment
'
;
import
{
timeout
}
from
'
vs/base/common/async
'
;
import
{
IWorkspaceContextService
}
from
'
vs/platform/workspace/common/workspace
'
;
type
CachedEditorInput
=
ResourceEditorInput
|
IFileEditorInput
|
UntitledTextEditorInput
;
type
OpenInEditorGroup
=
IEditorGroup
|
GroupIdentifier
|
SIDE_GROUP_TYPE
|
ACTIVE_GROUP_TYPE
;
...
...
@@ -59,15 +60,6 @@ export class EditorService extends Disposable implements EditorServiceImpl {
//#endregion
private
fileInputFactory
:
IFileInputFactory
;
private
readonly
openEditorHandlers
:
IOpenEditorOverrideHandler
[]
=
[];
private
lastActiveEditor
:
IEditorInput
|
undefined
=
undefined
;
private
readonly
editorsObserver
=
this
.
_register
(
this
.
instantiationService
.
createInstance
(
EditorsObserver
));
private
readonly
editorInputCache
=
new
ResourceMap
<
CachedEditorInput
>
();
constructor
(
@
IEditorGroupsService
private
readonly
editorGroupService
:
IEditorGroupsService
,
@
IUntitledTextEditorService
private
readonly
untitledTextEditorService
:
IUntitledTextEditorService
,
...
...
@@ -75,12 +67,11 @@ export class EditorService extends Disposable implements EditorServiceImpl {
@
ILabelService
private
readonly
labelService
:
ILabelService
,
@
IFileService
private
readonly
fileService
:
IFileService
,
@
IConfigurationService
private
readonly
configurationService
:
IConfigurationService
,
@
IEnvironmentService
private
readonly
environmentService
:
IEnvironmentService
@
IEnvironmentService
private
readonly
environmentService
:
IEnvironmentService
,
@
IWorkspaceContextService
private
readonly
contextService
:
IWorkspaceContextService
)
{
super
();
this
.
fileInputFactory
=
Registry
.
as
<
IEditorInputFactoryRegistry
>
(
EditorExtensions
.
EditorInputFactories
).
getFileInputFactory
();
this
.
onConfigurationUpdated
(
configurationService
.
getValue
<
IWorkbenchEditorConfiguration
>
());
this
.
registerListeners
();
...
...
@@ -94,6 +85,9 @@ export class EditorService extends Disposable implements EditorServiceImpl {
this
.
editorGroupService
.
onDidAddGroup
(
group
=>
this
.
registerGroupListeners
(
group
as
IEditorGroupView
));
this
.
editorsObserver
.
onDidChange
(()
=>
this
.
_onDidMostRecentlyActiveEditorsChange
.
fire
());
// Out of workspace file watchers
this
.
_register
(
this
.
onDidVisibleEditorsChange
(()
=>
this
.
handleVisibleEditorsChange
()));
// File changes & operations
this
.
_register
(
this
.
fileService
.
onDidRunOperation
(
e
=>
this
.
onDidRunFileOperation
(
e
)));
this
.
_register
(
this
.
fileService
.
onDidFilesChange
(
e
=>
this
.
onDidFilesChange
(
e
)));
...
...
@@ -102,6 +96,10 @@ export class EditorService extends Disposable implements EditorServiceImpl {
this
.
_register
(
this
.
configurationService
.
onDidChangeConfiguration
(
e
=>
this
.
onConfigurationUpdated
(
this
.
configurationService
.
getValue
<
IWorkbenchEditorConfiguration
>
())));
}
//#region Editor & group event handlers
private
lastActiveEditor
:
IEditorInput
|
undefined
=
undefined
;
private
onEditorsRestored
():
void
{
// Register listeners to each opened group
...
...
@@ -163,25 +161,51 @@ export class EditorService extends Disposable implements EditorServiceImpl {
});
}
private
onGroupWillOpenEditor
(
group
:
IEditorGroup
,
event
:
IEditorOpeningEvent
):
void
{
if
(
event
.
options
&&
event
.
options
.
ignoreOverrides
)
{
return
;
}
//#endregion
for
(
const
handler
of
this
.
openEditorHandlers
)
{
const
result
=
handler
(
event
.
editor
,
event
.
options
,
group
);
const
override
=
result
?.
override
;
if
(
override
)
{
event
.
prevent
((()
=>
override
.
then
(
editor
=>
withNullAsUndefined
(
editor
))));
break
;
//#region Visible Editors Change: Install file watchers for out of workspace resources that became visible
private
readonly
activeOutOfWorkspaceWatchers
=
new
ResourceMap
<
IDisposable
>
();
private
handleVisibleEditorsChange
():
void
{
const
visibleOutOfWorkspaceResources
=
new
ResourceMap
<
URI
>
();
for
(
const
editor
of
this
.
visibleEditors
)
{
const
resources
=
distinct
(
coalesce
([
toResource
(
editor
,
{
supportSideBySide
:
SideBySideEditorChoice
.
MASTER
}),
toResource
(
editor
,
{
supportSideBySide
:
SideBySideEditorChoice
.
DETAILS
})
]),
resource
=>
resource
.
toString
());
for
(
const
resource
of
resources
)
{
if
(
this
.
fileService
.
canHandleResource
(
resource
)
&&
!
this
.
contextService
.
isInsideWorkspace
(
resource
))
{
visibleOutOfWorkspaceResources
.
set
(
resource
,
resource
);
}
}
}
// Handle no longer visible out of workspace resources
this
.
activeOutOfWorkspaceWatchers
.
keys
().
forEach
(
resource
=>
{
if
(
!
visibleOutOfWorkspaceResources
.
get
(
resource
))
{
dispose
(
this
.
activeOutOfWorkspaceWatchers
.
get
(
resource
));
this
.
activeOutOfWorkspaceWatchers
.
delete
(
resource
);
}
});
// Handle newly visible out of workspace resources
visibleOutOfWorkspaceResources
.
forEach
(
resource
=>
{
if
(
!
this
.
activeOutOfWorkspaceWatchers
.
get
(
resource
))
{
const
disposable
=
this
.
fileService
.
watch
(
resource
);
this
.
activeOutOfWorkspaceWatchers
.
set
(
resource
,
disposable
);
}
});
}
//#endregion
//#region File Changes: Close editors of deleted files unless configured otherwise
private
closeOnFileDelete
:
boolean
=
false
;
private
fileInputFactory
=
Registry
.
as
<
IEditorInputFactoryRegistry
>
(
EditorExtensions
.
EditorInputFactories
).
getFileInputFactory
();
private
onConfigurationUpdated
(
configuration
:
IWorkbenchEditorConfiguration
):
void
{
if
(
typeof
configuration
.
workbench
?.
editor
?.
closeOnFileDelete
===
'
boolean
'
)
{
this
.
closeOnFileDelete
=
configuration
.
workbench
.
editor
.
closeOnFileDelete
;
...
...
@@ -285,6 +309,10 @@ export class EditorService extends Disposable implements EditorServiceImpl {
//#endregion
//#region Editor accessors
private
readonly
editorsObserver
=
this
.
_register
(
this
.
instantiationService
.
createInstance
(
EditorsObserver
));
get
activeControl
():
IVisibleEditor
|
undefined
{
return
this
.
editorGroupService
.
activeGroup
?.
activeControl
;
}
...
...
@@ -354,8 +382,12 @@ export class EditorService extends Disposable implements EditorServiceImpl {
return
coalesce
(
this
.
editorGroupService
.
groups
.
map
(
group
=>
group
.
activeEditor
));
}
//#endregion
//#region preventOpenEditor()
private
readonly
openEditorHandlers
:
IOpenEditorOverrideHandler
[]
=
[];
overrideOpenEditor
(
handler
:
IOpenEditorOverrideHandler
):
IDisposable
{
this
.
openEditorHandlers
.
push
(
handler
);
...
...
@@ -367,6 +399,21 @@ export class EditorService extends Disposable implements EditorServiceImpl {
});
}
private
onGroupWillOpenEditor
(
group
:
IEditorGroup
,
event
:
IEditorOpeningEvent
):
void
{
if
(
event
.
options
&&
event
.
options
.
ignoreOverrides
)
{
return
;
}
for
(
const
handler
of
this
.
openEditorHandlers
)
{
const
result
=
handler
(
event
.
editor
,
event
.
options
,
group
);
const
override
=
result
?.
override
;
if
(
override
)
{
event
.
prevent
((()
=>
override
.
then
(
editor
=>
withNullAsUndefined
(
editor
))));
break
;
}
}
}
//#endregion
//#region openEditor()
...
...
@@ -645,6 +692,8 @@ export class EditorService extends Disposable implements EditorServiceImpl {
//#region createInput()
private
readonly
editorInputCache
=
new
ResourceMap
<
CachedEditorInput
>
();
createInput
(
input
:
IEditorInputWithOptions
|
IEditorInput
|
IResourceEditor
):
EditorInput
{
// Typed Editor Input Support (EditorInput)
...
...
@@ -937,6 +986,14 @@ export class EditorService extends Disposable implements EditorServiceImpl {
}
//#endregion
dispose
():
void
{
super
.
dispose
();
// Dispose remaining watchers if any
this
.
activeOutOfWorkspaceWatchers
.
forEach
(
disposable
=>
dispose
(
disposable
));
this
.
activeOutOfWorkspaceWatchers
.
clear
();
}
}
export
interface
IEditorOpenHandler
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录