Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
徽霖
Vscode
提交
c8680b8f
V
Vscode
项目概览
徽霖
/
Vscode
通知
9
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,发现更多精彩内容 >>
提交
c8680b8f
编写于
5月 31, 2016
作者:
B
Benjamin Pasero
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Introduce event on input to indicate dirty state change (fixes #6953)
上级
afbe654b
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
252 addition
and
161 deletion
+252
-161
src/vs/workbench/browser/parts/editor/editorPart.ts
src/vs/workbench/browser/parts/editor/editorPart.ts
+12
-8
src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts
...workbench/browser/parts/editor/sideBySideEditorControl.ts
+23
-41
src/vs/workbench/common/editor.ts
src/vs/workbench/common/editor.ts
+10
-19
src/vs/workbench/common/editor/diffEditorInput.ts
src/vs/workbench/common/editor/diffEditorInput.ts
+3
-0
src/vs/workbench/common/editor/editorStacksModel.ts
src/vs/workbench/common/editor/editorStacksModel.ts
+33
-14
src/vs/workbench/common/editor/untitledEditorInput.ts
src/vs/workbench/common/editor/untitledEditorInput.ts
+27
-2
src/vs/workbench/common/events.ts
src/vs/workbench/common/events.ts
+0
-5
src/vs/workbench/electron-browser/window.ts
src/vs/workbench/electron-browser/window.ts
+5
-0
src/vs/workbench/parts/files/browser/editors/fileEditorInput.ts
.../workbench/parts/files/browser/editors/fileEditorInput.ts
+30
-4
src/vs/workbench/parts/files/browser/fileTracker.ts
src/vs/workbench/parts/files/browser/fileTracker.ts
+0
-41
src/vs/workbench/parts/files/test/browser/fileEditorInput.test.ts
...orkbench/parts/files/test/browser/fileEditorInput.test.ts
+12
-2
src/vs/workbench/parts/files/test/browser/textFileEditor.test.ts
...workbench/parts/files/test/browser/textFileEditor.test.ts
+20
-3
src/vs/workbench/services/history/browser/history.ts
src/vs/workbench/services/history/browser/history.ts
+17
-17
src/vs/workbench/test/browser/parts/quickOpen/quickopen.test.ts
.../workbench/test/browser/parts/quickOpen/quickopen.test.ts
+18
-5
src/vs/workbench/test/common/editor/editorStacksModel.test.ts
...vs/workbench/test/common/editor/editorStacksModel.test.ts
+42
-0
未找到文件。
src/vs/workbench/browser/parts/editor/editorPart.ts
浏览文件 @
c8680b8f
...
...
@@ -21,7 +21,7 @@ import errors = require('vs/base/common/errors');
import
{
Scope
as
MementoScope
}
from
'
vs/workbench/common/memento
'
;
import
{
Scope
}
from
'
vs/workbench/browser/actionBarRegistry
'
;
import
{
Part
}
from
'
vs/workbench/browser/part
'
;
import
{
EventType
as
WorkbenchEventType
,
Editor
InputEvent
,
Editor
Event
}
from
'
vs/workbench/common/events
'
;
import
{
EventType
as
WorkbenchEventType
,
EditorEvent
}
from
'
vs/workbench/common/events
'
;
import
{
IEditorRegistry
,
Extensions
as
EditorExtensions
,
BaseEditor
,
EditorDescriptor
}
from
'
vs/workbench/browser/parts/editor/baseEditor
'
;
import
{
EditorInput
,
EditorOptions
,
TextEditorOptions
,
ConfirmResult
}
from
'
vs/workbench/common/editor
'
;
import
{
BaseTextEditor
}
from
'
vs/workbench/browser/parts/editor/textEditor
'
;
...
...
@@ -122,17 +122,19 @@ export class EditorPart extends Part implements IEditorPart {
}
private
registerListeners
():
void
{
this
.
toUnbind
.
push
(
this
.
eventService
.
addListener2
(
WorkbenchEventType
.
EDITOR_INPUT_DIRTY_STATE_CHANGED
,
(
event
:
EditorInputEvent
)
=>
this
.
onEditorInputDirtyStateChanged
(
event
)));
this
.
toUnbind
.
push
(
this
.
stacks
.
onEditorDirty
(
identifier
=>
this
.
onEditorDirty
(
identifier
)));
this
.
toUnbind
.
push
(
this
.
stacks
.
onEditorDisposed
(
identifier
=>
this
.
onEditorDisposed
(
identifier
)));
}
private
onEditorInputDirtyStateChanged
(
event
:
EditorInputEvent
):
void
{
private
onEditorDirty
(
identifier
:
IEditorIdentifier
):
void
{
const
position
=
this
.
stacks
.
positionOfGroup
(
identifier
.
group
);
const
group
=
identifier
.
group
;
// we pin every editor that becomes dirty
across all groups
this
.
stacks
.
groups
.
forEach
(
group
=>
group
.
contains
(
event
.
editorInput
)
&&
this
.
pinEditor
(
this
.
stacks
.
positionOfGroup
(
group
),
event
.
editorInput
)
);
// we pin every editor that becomes dirty
this
.
pinEditor
(
position
,
identifier
.
editor
,
false
/* we update the UI right after */
);
// Update UI
this
.
sideBySideControl
.
updateTitleArea
(
event
.
editorInput
);
this
.
sideBySideControl
.
updateTitleArea
(
{
position
,
preview
:
group
.
previewEditor
,
editorCount
:
group
.
count
}
);
}
private
onEditorDisposed
(
identifier
:
IEditorIdentifier
):
void
{
...
...
@@ -1026,7 +1028,7 @@ export class EditorPart extends Part implements IEditorPart {
}
}
public
pinEditor
(
position
:
Position
,
input
:
EditorInput
):
void
{
public
pinEditor
(
position
:
Position
,
input
:
EditorInput
,
updateTitleArea
=
true
):
void
{
const
group
=
this
.
stacks
.
groupAt
(
position
);
if
(
group
)
{
if
(
group
.
isPinned
(
input
))
{
...
...
@@ -1037,7 +1039,9 @@ export class EditorPart extends Part implements IEditorPart {
group
.
pin
(
input
);
// Update UI
this
.
sideBySideControl
.
updateTitleArea
({
position
,
preview
:
group
.
previewEditor
,
editorCount
:
group
.
count
});
if
(
updateTitleArea
)
{
this
.
sideBySideControl
.
updateTitleArea
({
position
,
preview
:
group
.
previewEditor
,
editorCount
:
group
.
count
});
}
}
}
...
...
src/vs/workbench/browser/parts/editor/sideBySideEditorControl.ts
浏览文件 @
c8680b8f
...
...
@@ -20,7 +20,7 @@ import {Dimension, Builder, $} from 'vs/base/browser/builder';
import
{
Sash
,
ISashEvent
,
IVerticalSashLayoutProvider
}
from
'
vs/base/browser/ui/sash/sash
'
;
import
{
ProgressBar
}
from
'
vs/base/browser/ui/progressbar/progressbar
'
;
import
{
BaseEditor
,
IEditorInputActionContext
}
from
'
vs/workbench/browser/parts/editor/baseEditor
'
;
import
{
EditorInput
,
isInputRelated
}
from
'
vs/workbench/common/editor
'
;
import
{
EditorInput
}
from
'
vs/workbench/common/editor
'
;
import
{
EventType
as
BaseEventType
}
from
'
vs/base/common/events
'
;
import
DOM
=
require
(
'
vs/base/browser/dom
'
);
import
{
IActionItem
,
ActionsOrientation
,
Separator
}
from
'
vs/base/browser/ui/actionbar/actionbar
'
;
...
...
@@ -86,7 +86,6 @@ export interface ISideBySideEditorControl {
recreateTitleArea
(
states
:
ITitleAreaState
[]):
void
;
updateTitleArea
(
state
:
ITitleAreaState
):
void
;
updateTitleArea
(
input
:
EditorInput
):
void
;
clearTitleArea
(
position
:
Position
):
void
;
setTitleLabel
(
position
:
Position
,
input
:
EditorInput
,
isPinned
:
boolean
,
isActive
:
boolean
):
void
;
...
...
@@ -1178,49 +1177,32 @@ export class SideBySideEditorControl implements ISideBySideEditorControl, IVerti
return
actionItem
;
}
public
updateTitleArea
(
state
:
ITitleAreaState
):
void
;
public
updateTitleArea
(
input
:
EditorInput
):
void
;
public
updateTitleArea
(
arg1
:
any
):
void
{
public
updateTitleArea
(
state
:
ITitleAreaState
):
void
{
let
editor
=
this
.
visibleEditors
[
state
.
position
]
;
let
input
=
editor
?
editor
.
input
:
null
;
// Update all title areas that relate to given input if provided
if
(
arg1
instanceof
EditorInput
)
{
const
input
:
EditorInput
=
arg1
;
if
(
input
&&
editor
)
{
// Update the input title actions in each position according to the new status
POSITIONS
.
forEach
((
position
)
=>
{
if
(
this
.
visibleEditors
[
position
]
&&
isInputRelated
(
this
.
visibleEditors
[
position
].
input
,
input
))
{
this
.
closeEditorActions
[
position
].
class
=
input
.
isDirty
()
?
'
close-editor-dirty-action
'
:
'
close-editor-action
'
;
}
});
}
// Otherwise update specific title position
else
{
const
state
:
ITitleAreaState
=
arg1
;
let
editor
=
this
.
visibleEditors
[
state
.
position
];
let
input
=
editor
?
editor
.
input
:
null
;
if
(
input
&&
editor
)
{
// Dirty
this
.
closeEditorActions
[
state
.
position
].
class
=
input
.
isDirty
()
?
'
close-editor-dirty-action
'
:
'
close-editor-action
'
;
// Pinned
const
isPinned
=
!
input
.
matches
(
state
.
preview
);
if
(
isPinned
)
{
this
.
titleContainer
[
state
.
position
].
addClass
(
'
pinned
'
);
}
else
{
this
.
titleContainer
[
state
.
position
].
removeClass
(
'
pinned
'
);
}
// Pinned
const
isPinned
=
!
input
.
matches
(
state
.
preview
);
if
(
isPinned
)
{
this
.
titleContainer
[
state
.
position
].
addClass
(
'
pinned
'
);
}
else
{
this
.
titleContainer
[
state
.
position
].
removeClass
(
'
pinned
'
);
}
// Overflow
const
isOverflowing
=
state
.
editorCount
>
1
;
const
showEditorAction
=
this
.
showEditorsOfGroup
[
state
.
position
];
if
(
!
isOverflowing
)
{
showEditorAction
.
class
=
'
show-group-editors-overflowing-action-hidden
'
;
showEditorAction
.
enabled
=
false
;
}
else
{
showEditorAction
.
class
=
'
show-group-editors-action
'
;
showEditorAction
.
enabled
=
true
;
}
// Overflow
const
isOverflowing
=
state
.
editorCount
>
1
;
const
showEditorAction
=
this
.
showEditorsOfGroup
[
state
.
position
];
if
(
!
isOverflowing
)
{
showEditorAction
.
class
=
'
show-group-editors-overflowing-action-hidden
'
;
showEditorAction
.
enabled
=
false
;
}
else
{
showEditorAction
.
class
=
'
show-group-editors-action
'
;
showEditorAction
.
enabled
=
true
;
}
}
}
...
...
src/vs/workbench/common/editor.ts
浏览文件 @
c8680b8f
...
...
@@ -6,6 +6,7 @@
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
EventEmitter
}
from
'
vs/base/common/eventEmitter
'
;
import
Event
,
{
Emitter
}
from
'
vs/base/common/event
'
;
import
types
=
require
(
'
vs/base/common/types
'
);
import
URI
from
'
vs/base/common/uri
'
;
import
{
IEditor
,
IEditorViewState
,
IRange
}
from
'
vs/editor/common/editorCommon
'
;
...
...
@@ -24,14 +25,23 @@ export enum ConfirmResult {
* Each editor input is mapped to an editor that is capable of opening it through the Platform facade.
*/
export
abstract
class
EditorInput
extends
EventEmitter
implements
IEditorInput
{
protected
_onDidChangeDirty
:
Emitter
<
void
>
;
private
disposed
:
boolean
;
constructor
()
{
super
();
this
.
_onDidChangeDirty
=
new
Emitter
<
void
>
();
this
.
disposed
=
false
;
}
/**
* Fired when the dirty state of this input changes.
*/
public
get
onDidChangeDirty
():
Event
<
void
>
{
return
this
.
_onDidChangeDirty
.
event
;
}
/**
* Returns the name of this input that can be shown to the user. Examples include showing the name of the input
* above the editor area when the input is shown.
...
...
@@ -565,23 +575,4 @@ export function asFileEditorInput(obj: any, supportDiff?: boolean): IFileEditorI
let
i
=
<
IFileEditorInput
>
obj
;
return
i
instanceof
EditorInput
&&
types
.
areFunctions
(
i
.
setResource
,
i
.
setMime
,
i
.
setEncoding
,
i
.
getEncoding
,
i
.
getResource
,
i
.
getMime
)
?
i
:
null
;
}
export
function
isInputRelated
(
sourceInput
:
EditorInput
,
targetInput
:
EditorInput
):
boolean
{
if
(
!
sourceInput
||
!
targetInput
)
{
return
false
;
}
if
(
sourceInput
.
matches
(
targetInput
))
{
return
true
;
}
if
(
sourceInput
instanceof
BaseDiffEditorInput
)
{
let
modifiedInput
=
(
<
BaseDiffEditorInput
>
sourceInput
).
getModifiedInput
();
if
(
modifiedInput
&&
modifiedInput
.
matches
(
targetInput
))
{
return
true
;
}
}
return
false
;
}
\ No newline at end of file
src/vs/workbench/common/editor/diffEditorInput.ts
浏览文件 @
c8680b8f
...
...
@@ -57,6 +57,9 @@ export class DiffEditorInput extends BaseDiffEditorInput {
this
.
dispose
();
}
}));
// When the modified model gets dirty, re-emit this to the outside
this
.
_toUnbind
.
push
(
this
.
modifiedInput
.
onDidChangeDirty
(()
=>
this
.
_onDidChangeDirty
.
fire
()));
}
public
get
toUnbind
()
{
...
...
src/vs/workbench/common/editor/editorStacksModel.ts
浏览文件 @
c8680b8f
...
...
@@ -134,6 +134,7 @@ export class EditorGroup implements IEditorGroup {
private
_onEditorOpened
:
Emitter
<
EditorInput
>
;
private
_onEditorClosed
:
Emitter
<
IGroupEvent
>
;
private
_onEditorDisposed
:
Emitter
<
EditorInput
>
;
private
_onEditorDirty
:
Emitter
<
EditorInput
>
;
private
_onEditorMoved
:
Emitter
<
EditorInput
>
;
private
_onEditorPinned
:
Emitter
<
EditorInput
>
;
private
_onEditorUnpinned
:
Emitter
<
EditorInput
>
;
...
...
@@ -154,12 +155,13 @@ export class EditorGroup implements IEditorGroup {
this
.
_onEditorOpened
=
new
Emitter
<
EditorInput
>
();
this
.
_onEditorClosed
=
new
Emitter
<
IGroupEvent
>
();
this
.
_onEditorDisposed
=
new
Emitter
<
EditorInput
>
();
this
.
_onEditorDirty
=
new
Emitter
<
EditorInput
>
();
this
.
_onEditorMoved
=
new
Emitter
<
EditorInput
>
();
this
.
_onEditorPinned
=
new
Emitter
<
EditorInput
>
();
this
.
_onEditorUnpinned
=
new
Emitter
<
EditorInput
>
();
this
.
_onEditorChanged
=
new
Emitter
<
EditorInput
>
();
this
.
toDispose
.
push
(
this
.
_onEditorActivated
,
this
.
_onEditorOpened
,
this
.
_onEditorClosed
,
this
.
_onEditorDisposed
,
this
.
_onEditorMoved
,
this
.
_onEditorPinned
,
this
.
_onEditorUnpinned
,
this
.
_onEditorChanged
);
this
.
toDispose
.
push
(
this
.
_onEditorActivated
,
this
.
_onEditorOpened
,
this
.
_onEditorClosed
,
this
.
_onEditorDisposed
,
this
.
_onEditor
Dirty
,
this
.
_onEditor
Moved
,
this
.
_onEditorPinned
,
this
.
_onEditorUnpinned
,
this
.
_onEditorChanged
);
if
(
typeof
arg1
===
'
object
'
)
{
this
.
deserialize
(
arg1
);
...
...
@@ -200,6 +202,10 @@ export class EditorGroup implements IEditorGroup {
return
this
.
_onEditorDisposed
.
event
;
}
public
get
onEditorDirty
():
Event
<
EditorInput
>
{
return
this
.
_onEditorDirty
.
event
;
}
public
get
onEditorMoved
():
Event
<
EditorInput
>
{
return
this
.
_onEditorMoved
.
event
;
}
...
...
@@ -325,21 +331,26 @@ export class EditorGroup implements IEditorGroup {
}
private
hookEditorListeners
(
editor
:
EditorInput
):
void
{
const
unbind
:
IDisposable
[]
=
[];
// Re-emit disposal of editor input as our own event
const
l1
=
editor
.
addOneTimeDisposableListener
(
'
dispose
'
,
()
=>
{
unbind
.
push
(
editor
.
addOneTimeDisposableListener
(
'
dispose
'
,
()
=>
{
if
(
this
.
indexOf
(
editor
)
>=
0
)
{
this
.
_onEditorDisposed
.
fire
(
editor
);
}
});
}));
// Re-Emit dirty state changes
unbind
.
push
(
editor
.
onDidChangeDirty
(()
=>
{
this
.
_onEditorDirty
.
fire
(
editor
);
}));
// Clean up dispose listeners once the editor gets closed
const
l2
=
this
.
onEditorClosed
(
event
=>
{
unbind
.
push
(
this
.
onEditorClosed
(
event
=>
{
if
(
event
.
editor
.
matches
(
editor
))
{
l1
.
dispose
();
l2
.
dispose
();
dispose
(
unbind
);
}
});
})
)
;
}
public
closeEditor
(
editor
:
EditorInput
,
openNext
=
true
):
void
{
...
...
@@ -666,6 +677,7 @@ export class EditorStacksModel implements IEditorStacksModel {
private
_onGroupRenamed
:
Emitter
<
EditorGroup
>
;
private
_onModelChanged
:
Emitter
<
EditorGroup
>
;
private
_onEditorDisposed
:
Emitter
<
IEditorIdentifier
>
;
private
_onEditorDirty
:
Emitter
<
IEditorIdentifier
>
;
constructor
(
@
IStorageService
private
storageService
:
IStorageService
,
...
...
@@ -687,8 +699,9 @@ export class EditorStacksModel implements IEditorStacksModel {
this
.
_onGroupRenamed
=
new
Emitter
<
EditorGroup
>
();
this
.
_onModelChanged
=
new
Emitter
<
EditorGroup
>
();
this
.
_onEditorDisposed
=
new
Emitter
<
IEditorIdentifier
>
();
this
.
_onEditorDirty
=
new
Emitter
<
IEditorIdentifier
>
();
this
.
toDispose
.
push
(
this
.
_onGroupOpened
,
this
.
_onGroupClosed
,
this
.
_onGroupActivated
,
this
.
_onGroupMoved
,
this
.
_onGroupRenamed
,
this
.
_onModelChanged
,
this
.
_onEditorDisposed
);
this
.
toDispose
.
push
(
this
.
_onGroupOpened
,
this
.
_onGroupClosed
,
this
.
_onGroupActivated
,
this
.
_onGroupMoved
,
this
.
_onGroupRenamed
,
this
.
_onModelChanged
,
this
.
_onEditorDisposed
,
this
.
_onEditorDirty
);
this
.
registerListeners
();
}
...
...
@@ -725,6 +738,10 @@ export class EditorStacksModel implements IEditorStacksModel {
return
this
.
_onEditorDisposed
.
event
;
}
public
get
onEditorDirty
():
Event
<
IEditorIdentifier
>
{
return
this
.
_onEditorDirty
.
event
;
}
public
get
groups
():
EditorGroup
[]
{
this
.
ensureLoaded
();
...
...
@@ -1081,14 +1098,16 @@ export class EditorStacksModel implements IEditorStacksModel {
this
.
groupToIdentifier
[
group
.
id
]
=
group
;
// Funnel editor changes in the group through our event aggregator
const
l1
=
group
.
onEditorChanged
(
e
=>
this
.
_onModelChanged
.
fire
(
group
));
const
l2
=
group
.
onEditorClosed
(
e
=>
this
.
onEditorClosed
(
e
));
const
l3
=
group
.
onEditorDisposed
(
editor
=>
this
.
_onEditorDisposed
.
fire
({
editor
,
group
}));
const
l4
=
this
.
onGroupClosed
(
g
=>
{
const
unbind
:
IDisposable
[]
=
[];
unbind
.
push
(
group
.
onEditorChanged
(
e
=>
this
.
_onModelChanged
.
fire
(
group
)));
unbind
.
push
(
group
.
onEditorClosed
(
e
=>
this
.
onEditorClosed
(
e
)));
unbind
.
push
(
group
.
onEditorDisposed
(
editor
=>
this
.
_onEditorDisposed
.
fire
({
editor
,
group
})));
unbind
.
push
(
group
.
onEditorDirty
(
editor
=>
this
.
_onEditorDirty
.
fire
({
editor
,
group
})));
unbind
.
push
(
this
.
onGroupClosed
(
g
=>
{
if
(
g
===
group
)
{
dispose
(
l1
,
l2
,
l3
,
l4
);
dispose
(
unbind
);
}
});
})
)
;
return
group
;
}
...
...
src/vs/workbench/common/editor/untitledEditorInput.ts
浏览文件 @
c8680b8f
...
...
@@ -15,6 +15,9 @@ import {IInstantiationService} from 'vs/platform/instantiation/common/instantiat
import
{
ILifecycleService
}
from
'
vs/platform/lifecycle/common/lifecycle
'
;
import
{
IWorkspaceContextService
}
from
'
vs/platform/workspace/common/workspace
'
;
import
{
IModeService
}
from
'
vs/editor/common/services/modeService
'
;
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
IEventService
}
from
'
vs/platform/event/common/event
'
;
import
{
EventType
as
WorkbenchEventType
,
UntitledEditorEvent
}
from
'
vs/workbench/common/events
'
;
import
{
ITextFileService
}
from
'
vs/workbench/parts/files/common/files
'
;
// TODO@Ben layer breaker
...
...
@@ -31,6 +34,8 @@ export class UntitledEditorInput extends AbstractUntitledEditorInput {
private
modeId
:
string
;
private
cachedModel
:
UntitledEditorModel
;
private
toUnbind
:
IDisposable
[];
constructor
(
resource
:
URI
,
hasAssociatedFilePath
:
boolean
,
...
...
@@ -39,13 +44,28 @@ export class UntitledEditorInput extends AbstractUntitledEditorInput {
@
ILifecycleService
private
lifecycleService
:
ILifecycleService
,
@
IWorkspaceContextService
private
contextService
:
IWorkspaceContextService
,
@
IModeService
private
modeService
:
IModeService
,
@
ITextFileService
private
textFileService
:
ITextFileService
@
ITextFileService
private
textFileService
:
ITextFileService
,
@
IEventService
private
eventService
:
IEventService
)
{
super
();
this
.
resource
=
resource
;
this
.
hasAssociatedFilePath
=
hasAssociatedFilePath
;
this
.
modeId
=
modeId
;
this
.
toUnbind
=
[];
this
.
registerListeners
();
}
private
registerListeners
():
void
{
this
.
toUnbind
.
push
(
this
.
eventService
.
addListener2
(
WorkbenchEventType
.
UNTITLED_FILE_DELETED
,
(
e
:
UntitledEditorEvent
)
=>
this
.
onDirtyStateChange
(
e
)));
this
.
toUnbind
.
push
(
this
.
eventService
.
addListener2
(
WorkbenchEventType
.
UNTITLED_FILE_DIRTY
,
(
e
:
UntitledEditorEvent
)
=>
this
.
onDirtyStateChange
(
e
)));
}
private
onDirtyStateChange
(
e
:
UntitledEditorEvent
):
void
{
if
(
e
.
resource
.
toString
()
===
this
.
resource
.
toString
())
{
this
.
_onDidChangeDirty
.
fire
();
}
}
public
getTypeId
():
string
{
...
...
@@ -158,11 +178,16 @@ export class UntitledEditorInput extends AbstractUntitledEditorInput {
}
public
dispose
():
void
{
super
.
dispose
();
// Listeners
dispose
(
this
.
toUnbind
);
// Model
if
(
this
.
cachedModel
)
{
this
.
cachedModel
.
dispose
();
this
.
cachedModel
=
null
;
}
super
.
dispose
();
}
}
\ No newline at end of file
src/vs/workbench/common/events.ts
浏览文件 @
c8680b8f
...
...
@@ -52,11 +52,6 @@ export class EventType {
*/
static
EDITOR_INPUT_CHANGED
=
'
editorInputChanged
'
;
/**
* Event type for when the editor input dirty state changed.
*/
static
EDITOR_INPUT_DIRTY_STATE_CHANGED
=
'
editorInputDirtyStateChanged
'
;
/**
* Event type for when the editor input failed to be set to the editor.
*/
...
...
src/vs/workbench/electron-browser/window.ts
浏览文件 @
c8680b8f
...
...
@@ -53,6 +53,11 @@ export class ElectronWindow {
// React to editor input changes (Mac only)
if
(
platform
.
platform
===
platform
.
Platform
.
Mac
)
{
this
.
eventService
.
addListener2
(
EventType
.
EDITOR_INPUT_CHANGED
,
(
e
:
EditorEvent
)
=>
{
let
activeEditor
=
this
.
editorService
.
getActiveEditor
();
if
(
activeEditor
!==
e
.
editor
)
{
return
;
// only care about active editor
}
let
fileInput
=
workbenchEditorCommon
.
asFileEditorInput
(
e
.
editorInput
,
true
);
let
representedFilename
=
''
;
if
(
fileInput
)
{
...
...
src/vs/workbench/parts/files/browser/editors/fileEditorInput.ts
浏览文件 @
c8680b8f
...
...
@@ -18,10 +18,12 @@ import {IEditorRegistry, Extensions, EditorDescriptor} from 'vs/workbench/browse
import
{
BinaryEditorModel
}
from
'
vs/workbench/common/editor/binaryEditorModel
'
;
import
{
IFileOperationResult
,
FileOperationResult
}
from
'
vs/platform/files/common/files
'
;
import
{
FileEditorDescriptor
}
from
'
vs/workbench/parts/files/browser/files
'
;
import
{
ITextFileService
,
BINARY_FILE_EDITOR_ID
,
FILE_EDITOR_INPUT_ID
,
FileEditorInput
as
CommonFileEditorInput
,
AutoSaveMode
,
ModelState
}
from
'
vs/workbench/parts/files/common/files
'
;
import
{
ITextFileService
,
BINARY_FILE_EDITOR_ID
,
FILE_EDITOR_INPUT_ID
,
FileEditorInput
as
CommonFileEditorInput
,
AutoSaveMode
,
ModelState
,
EventType
as
FileEventType
,
TextFileChangeEvent
}
from
'
vs/workbench/parts/files/common/files
'
;
import
{
CACHE
,
TextFileEditorModel
}
from
'
vs/workbench/parts/files/common/editors/textFileEditorModel
'
;
import
{
IWorkspaceContextService
}
from
'
vs/workbench/services/workspace/common/contextService
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
IEventService
}
from
'
vs/platform/event/common/event
'
;
/**
* A file editor input is the input type for the file editor of file system resources.
...
...
@@ -42,6 +44,8 @@ export class FileEditorInput extends CommonFileEditorInput {
private
description
:
string
;
private
verboseDescription
:
string
;
private
toUnbind
:
IDisposable
[];
/**
* An editor input who's contents are retrieved from file services.
*/
...
...
@@ -49,17 +53,35 @@ export class FileEditorInput extends CommonFileEditorInput {
resource
:
URI
,
mime
:
string
,
preferredEncoding
:
string
,
@
IEventService
private
eventService
:
IEventService
,
@
IInstantiationService
private
instantiationService
:
IInstantiationService
,
@
IWorkspaceContextService
private
contextService
:
IWorkspaceContextService
,
@
ITextFileService
private
textFileService
:
ITextFileService
)
{
super
();
this
.
toUnbind
=
[];
if
(
resource
)
{
this
.
setResource
(
resource
);
this
.
setMime
(
mime
||
guessMimeTypes
(
this
.
resource
.
fsPath
).
join
(
'
,
'
));
this
.
preferredEncoding
=
preferredEncoding
;
}
this
.
registerListeners
();
}
private
registerListeners
():
void
{
this
.
toUnbind
.
push
(
this
.
eventService
.
addListener2
(
FileEventType
.
FILE_DIRTY
,
(
e
:
TextFileChangeEvent
)
=>
this
.
onDirtyStateChange
(
e
)));
this
.
toUnbind
.
push
(
this
.
eventService
.
addListener2
(
FileEventType
.
FILE_SAVE_ERROR
,
(
e
:
TextFileChangeEvent
)
=>
this
.
onDirtyStateChange
(
e
)));
this
.
toUnbind
.
push
(
this
.
eventService
.
addListener2
(
FileEventType
.
FILE_SAVED
,
(
e
:
TextFileChangeEvent
)
=>
this
.
onDirtyStateChange
(
e
)));
this
.
toUnbind
.
push
(
this
.
eventService
.
addListener2
(
FileEventType
.
FILE_REVERTED
,
(
e
:
TextFileChangeEvent
)
=>
this
.
onDirtyStateChange
(
e
)));
}
private
onDirtyStateChange
(
e
:
TextFileChangeEvent
):
void
{
if
(
e
.
resource
.
toString
()
===
this
.
resource
.
toString
())
{
this
.
_onDidChangeDirty
.
fire
();
}
}
public
setResource
(
resource
:
URI
):
void
{
...
...
@@ -254,9 +276,10 @@ export class FileEditorInput extends CommonFileEditorInput {
}
private
indexOfClient
():
number
{
if
(
!
types
.
isUndefinedOrNull
(
FileEditorInput
.
FILE_EDITOR_MODEL_CLIENTS
[
this
.
resource
.
toString
()]))
{
for
(
let
i
=
0
;
i
<
FileEditorInput
.
FILE_EDITOR_MODEL_CLIENTS
[
this
.
resource
.
toString
()].
length
;
i
++
)
{
let
client
=
FileEditorInput
.
FILE_EDITOR_MODEL_CLIENTS
[
this
.
resource
.
toString
()][
i
];
const
inputs
=
FileEditorInput
.
FILE_EDITOR_MODEL_CLIENTS
[
this
.
resource
.
toString
()];
if
(
inputs
)
{
for
(
let
i
=
0
;
i
<
inputs
.
length
;
i
++
)
{
let
client
=
inputs
[
i
];
if
(
client
===
this
)
{
return
i
;
}
...
...
@@ -291,6 +314,9 @@ export class FileEditorInput extends CommonFileEditorInput {
public
dispose
(
force
?:
boolean
):
void
{
// Listeners
dispose
(
this
.
toUnbind
);
// TextFileEditorModel
let
cachedModel
=
CACHE
.
get
(
this
.
resource
);
if
(
cachedModel
)
{
...
...
src/vs/workbench/parts/files/browser/fileTracker.ts
浏览文件 @
c8680b8f
...
...
@@ -10,7 +10,6 @@ import nls = require('vs/nls');
import
{
MIME_UNKNOWN
}
from
'
vs/base/common/mime
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
paths
=
require
(
'
vs/base/common/paths
'
);
import
arrays
=
require
(
'
vs/base/common/arrays
'
);
import
{
DiffEditorInput
}
from
'
vs/workbench/common/editor/diffEditorInput
'
;
import
{
EditorInput
,
EditorOptions
}
from
'
vs/workbench/common/editor
'
;
import
{
BaseEditor
}
from
'
vs/workbench/browser/parts/editor/baseEditor
'
;
...
...
@@ -82,49 +81,32 @@ export class FileTracker implements IWorkbenchContribution {
}
private
onTextFileDirty
(
e
:
TextFileChangeEvent
):
void
{
this
.
emitInputDirtyStateChangeEvent
(
e
.
resource
,
true
);
if
(
this
.
textFileService
.
getAutoSaveMode
()
!==
AutoSaveMode
.
AFTER_SHORT_DELAY
)
{
this
.
updateActivityBadge
();
// no indication needed when auto save is enabled for short delay
}
}
private
onTextFileSaveError
(
e
:
TextFileChangeEvent
):
void
{
this
.
emitInputDirtyStateChangeEvent
(
e
.
resource
,
true
);
this
.
updateActivityBadge
();
}
private
onTextFileSaved
(
e
:
TextFileChangeEvent
):
void
{
this
.
emitInputDirtyStateChangeEvent
(
e
.
resource
,
false
);
if
(
this
.
lastDirtyCount
>
0
)
{
this
.
updateActivityBadge
();
}
}
private
onTextFileReverted
(
e
:
TextFileChangeEvent
):
void
{
this
.
emitInputDirtyStateChangeEvent
(
e
.
resource
,
false
);
if
(
this
.
lastDirtyCount
>
0
)
{
this
.
updateActivityBadge
();
}
}
private
onUntitledEditorDirty
(
e
:
UntitledEditorEvent
):
void
{
let
input
=
this
.
untitledEditorService
.
get
(
e
.
resource
);
if
(
input
)
{
this
.
eventService
.
emit
(
WorkbenchEventType
.
EDITOR_INPUT_DIRTY_STATE_CHANGED
,
new
EditorInputEvent
(
input
));
}
this
.
updateActivityBadge
();
}
private
onUntitledEditorDeleted
(
e
:
UntitledEditorEvent
):
void
{
let
input
=
this
.
untitledEditorService
.
get
(
e
.
resource
);
if
(
input
)
{
this
.
eventService
.
emit
(
WorkbenchEventType
.
EDITOR_INPUT_DIRTY_STATE_CHANGED
,
new
EditorInputEvent
(
input
));
}
if
(
this
.
lastDirtyCount
>
0
)
{
this
.
updateActivityBadge
();
}
...
...
@@ -140,29 +122,6 @@ export class FileTracker implements IWorkbenchContribution {
}
}
private
emitInputDirtyStateChangeEvent
(
resource
:
URI
,
gotDirty
:
boolean
):
void
{
// Find all file editor inputs that are open from the given file resource and emit a editor input state change event.
// We could do all of this within the file editor input but having all the file change listeners in
// one place is more elegant and keeps the logic together at once place.
const
editors
=
arrays
.
flatten
(
this
.
stacks
.
groups
.
map
(
g
=>
g
.
getEditors
()));
editors
.
forEach
(
input
=>
{
if
(
this
.
matchesResource
(
input
,
resource
))
{
this
.
eventService
.
emit
(
WorkbenchEventType
.
EDITOR_INPUT_DIRTY_STATE_CHANGED
,
new
EditorInputEvent
(
input
));
}
});
}
private
matchesResource
(
input
:
EditorInput
,
resource
:
URI
):
boolean
{
// Diff Editor Input
if
(
input
instanceof
DiffEditorInput
)
{
input
=
(
<
DiffEditorInput
>
input
).
getModifiedInput
();
}
return
input
instanceof
FileEditorInput
&&
input
.
getResource
().
toString
()
===
resource
.
toString
();
}
// Note: there is some duplication with the other file event handler below. Since we cannot always rely on the disk events
// carrying all necessary data in all environments, we also use the local file events to make sure operations are handled.
// In any case there is no guarantee if the local event is fired first or the disk one. Thus, code must handle the case
...
...
src/vs/workbench/parts/files/test/browser/fileEditorInput.test.ts
浏览文件 @
c8680b8f
...
...
@@ -115,8 +115,18 @@ suite('Files - FileEditorInput', () => {
});
test
(
'
Input.matches() - FileEditorInput
'
,
function
()
{
let
fileEditorInput
=
new
FileEditorInput
(
toResource
(
'
/foo/bar/updatefile.js
'
),
'
text/javascript
'
,
void
0
,
void
0
,
void
0
,
void
0
);
let
contentEditorInput2
=
new
FileEditorInput
(
toResource
(
'
/foo/bar/updatefile.js
'
),
'
text/javascript
'
,
void
0
,
void
0
,
void
0
,
void
0
);
let
eventService
=
new
TestEventService
();
let
contextService
=
new
TestContextService
();
let
services
=
new
ServiceCollection
();
let
instantiationService
=
new
InstantiationService
(
services
);
services
.
set
(
IEventService
,
eventService
);
services
.
set
(
IWorkspaceContextService
,
contextService
);
services
.
set
(
ITextFileService
,
<
ITextFileService
>
instantiationService
.
createInstance
(
<
any
>
TextFileService
));
let
fileEditorInput
=
instantiationService
.
createInstance
(
FileEditorInput
,
toResource
(
'
/foo/bar/updatefile.js
'
),
'
text/javascript
'
,
void
0
);
let
contentEditorInput2
=
instantiationService
.
createInstance
(
FileEditorInput
,
toResource
(
'
/foo/bar/updatefile.js
'
),
'
text/javascript
'
,
void
0
);
assert
.
strictEqual
(
fileEditorInput
.
matches
(
null
),
false
);
assert
.
strictEqual
(
fileEditorInput
.
matches
(
fileEditorInput
),
true
);
...
...
src/vs/workbench/parts/files/test/browser/textFileEditor.test.ts
浏览文件 @
c8680b8f
...
...
@@ -13,6 +13,13 @@ import {Registry} from 'vs/platform/platform';
import
{
SyncDescriptor
}
from
'
vs/platform/instantiation/common/descriptors
'
;
import
{
FileEditorInput
}
from
'
vs/workbench/parts/files/browser/editors/fileEditorInput
'
;
import
{
Extensions
}
from
'
vs/workbench/browser/parts/editor/baseEditor
'
;
import
{
TestEventService
,
TestContextService
}
from
'
vs/workbench/test/common/servicesTestUtils
'
;
import
{
IEventService
}
from
'
vs/platform/event/common/event
'
;
import
{
IWorkspaceContextService
}
from
'
vs/platform/workspace/common/workspace
'
;
import
{
ServiceCollection
}
from
'
vs/platform/instantiation/common/serviceCollection
'
;
import
{
InstantiationService
}
from
'
vs/platform/instantiation/common/instantiationService
'
;
import
{
ITextFileService
}
from
'
vs/workbench/parts/files/common/files
'
;
import
{
TextFileService
}
from
'
vs/workbench/parts/files/browser/textFileServices
'
;
const
ExtensionId
=
Extensions
.
Editors
;
...
...
@@ -37,9 +44,19 @@ suite('Files - TextFileEditor', () => {
equal
(
Registry
.
as
(
ExtensionId
).
getEditors
().
length
,
oldEditorCnt
+
2
);
equal
(
Registry
.
as
(
ExtensionId
).
getEditorInputs
().
length
,
oldInputCnt
+
2
);
strictEqual
(
Registry
.
as
(
ExtensionId
).
getEditor
(
new
FileEditorInput
(
URI
.
file
(
join
(
'
C:
\\
'
,
'
/foo/bar/foobar.html
'
)),
'
test-text/html
'
,
void
0
,
void
0
,
void
0
,
void
0
)),
d1
);
strictEqual
(
Registry
.
as
(
ExtensionId
).
getEditor
(
new
FileEditorInput
(
URI
.
file
(
join
(
'
C:
\\
'
,
'
/foo/bar/foobar.js
'
)),
'
test-text/javascript
'
,
void
0
,
void
0
,
void
0
,
void
0
)),
d1
);
strictEqual
(
Registry
.
as
(
ExtensionId
).
getEditor
(
new
FileEditorInput
(
URI
.
file
(
join
(
'
C:
\\
'
,
'
/foo/bar/foobar.css
'
)),
'
test-text/css
'
,
void
0
,
void
0
,
void
0
,
void
0
)),
d2
);
let
eventService
=
new
TestEventService
();
let
contextService
=
new
TestContextService
();
let
services
=
new
ServiceCollection
();
let
instantiationService
=
new
InstantiationService
(
services
);
services
.
set
(
IEventService
,
eventService
);
services
.
set
(
IWorkspaceContextService
,
contextService
);
services
.
set
(
ITextFileService
,
<
ITextFileService
>
instantiationService
.
createInstance
(
<
any
>
TextFileService
));
strictEqual
(
Registry
.
as
(
ExtensionId
).
getEditor
(
instantiationService
.
createInstance
(
FileEditorInput
,
URI
.
file
(
join
(
'
C:
\\
'
,
'
/foo/bar/foobar.html
'
)),
'
test-text/html
'
,
void
0
)),
d1
);
strictEqual
(
Registry
.
as
(
ExtensionId
).
getEditor
(
instantiationService
.
createInstance
(
FileEditorInput
,
URI
.
file
(
join
(
'
C:
\\
'
,
'
/foo/bar/foobar.js
'
)),
'
test-text/javascript
'
,
void
0
)),
d1
);
strictEqual
(
Registry
.
as
(
ExtensionId
).
getEditor
(
instantiationService
.
createInstance
(
FileEditorInput
,
URI
.
file
(
join
(
'
C:
\\
'
,
'
/foo/bar/foobar.css
'
)),
'
test-text/css
'
,
void
0
)),
d2
);
Registry
.
as
(
ExtensionId
).
setEditors
(
oldEditors
);
});
...
...
src/vs/workbench/services/history/browser/history.ts
浏览文件 @
c8680b8f
...
...
@@ -11,7 +11,7 @@ import {EventType} from 'vs/base/common/events';
import
{
IEditor
as
IBaseEditor
}
from
'
vs/platform/editor/common/editor
'
;
import
{
TextEditorOptions
,
EditorInput
}
from
'
vs/workbench/common/editor
'
;
import
{
BaseTextEditor
}
from
'
vs/workbench/browser/parts/editor/textEditor
'
;
import
{
EditorEvent
,
TextEditorSelectionEvent
,
EventType
as
WorkbenchEventType
,
EditorInputEvent
}
from
'
vs/workbench/common/events
'
;
import
{
EditorEvent
,
TextEditorSelectionEvent
,
EventType
as
WorkbenchEventType
}
from
'
vs/workbench/common/events
'
;
import
{
IWorkbenchEditorService
}
from
'
vs/workbench/services/editor/common/editorService
'
;
import
{
IHistoryService
}
from
'
vs/workbench/services/history/common/history
'
;
import
{
Selection
}
from
'
vs/editor/common/core/selection
'
;
...
...
@@ -28,7 +28,6 @@ export class EditorState {
private
static
EDITOR_SELECTION_THRESHOLD
=
5
;
// number of lines to move in editor to justify for new state
constructor
(
private
_editorInput
:
IEditorInput
,
private
_selection
:
Selection
)
{
//
}
public
get
editorInput
():
IEditorInput
{
...
...
@@ -68,6 +67,7 @@ interface IInputWithPath {
export
abstract
class
BaseHistoryService
{
protected
toUnbind
:
IDisposable
[];
private
activeEditorUnbind
:
IDisposable
;
constructor
(
private
eventService
:
IEventService
,
...
...
@@ -82,25 +82,10 @@ export abstract class BaseHistoryService {
// Editor Input Changes
this
.
toUnbind
.
push
(
this
.
eventService
.
addListener2
(
WorkbenchEventType
.
EDITOR_INPUT_CHANGED
,
(
e
:
EditorEvent
)
=>
this
.
onEditorInputChanged
(
e
)));
// Editor Input State Changes
this
.
toUnbind
.
push
(
this
.
eventService
.
addListener2
(
WorkbenchEventType
.
EDITOR_INPUT_DIRTY_STATE_CHANGED
,
(
e
:
EditorInputEvent
)
=>
this
.
onEditorInputDirtyStateChanged
(
e
.
editorInput
)));
// Text Editor Selection Changes
this
.
toUnbind
.
push
(
this
.
eventService
.
addListener2
(
WorkbenchEventType
.
TEXT_EDITOR_SELECTION_CHANGED
,
(
event
:
TextEditorSelectionEvent
)
=>
this
.
onTextEditorSelectionChanged
(
event
)));
}
private
onEditorInputDirtyStateChanged
(
input
:
IEditorInput
):
void
{
// If an active editor is set, but is different from the one from the event, prevent update because the editor is not active.
let
activeEditor
=
this
.
editorService
.
getActiveEditor
();
if
(
activeEditor
&&
!
input
.
matches
(
activeEditor
.
input
))
{
return
;
}
// Calculate New Window Title
this
.
updateWindowTitle
(
input
);
}
private
onTextEditorSelectionChanged
(
event
:
TextEditorSelectionEvent
):
void
{
// If an active editor is set, but is different from the one from the event, prevent update because the editor is not active.
...
...
@@ -115,7 +100,22 @@ export abstract class BaseHistoryService {
}
private
onEditorInputChanged
(
event
:
EditorEvent
):
void
{
// Propagate to history
this
.
onEditorEvent
(
event
.
editor
);
// Stop old listener
if
(
this
.
activeEditorUnbind
)
{
this
.
activeEditorUnbind
.
dispose
();
}
// Apply listener for dirty changes
let
activeInput
=
this
.
editorService
.
getActiveEditorInput
();
if
(
activeInput
instanceof
EditorInput
)
{
this
.
activeEditorUnbind
=
activeInput
.
onDidChangeDirty
(()
=>
{
this
.
updateWindowTitle
(
activeInput
);
// Calculate New Window Title when dirty state changes
});
}
}
private
onEditorEvent
(
editor
:
IBaseEditor
):
void
{
...
...
src/vs/workbench/test/browser/parts/quickOpen/quickopen.test.ts
浏览文件 @
c8680b8f
...
...
@@ -16,7 +16,9 @@ import {QuickOpenController} from 'vs/workbench/browser/parts/quickopen/quickOpe
import
{
Mode
}
from
'
vs/base/parts/quickopen/common/quickOpen
'
;
import
{
StringEditorInput
}
from
'
vs/workbench/common/editor/stringEditorInput
'
;
import
{
EditorInput
}
from
'
vs/workbench/common/editor
'
;
import
{
IWorkspaceContextService
}
from
'
vs/platform/workspace/common/workspace
'
;
import
{
isEmptyObject
}
from
'
vs/base/common/types
'
;
import
{
IEventService
}
from
'
vs/platform/event/common/event
'
;
import
{
join
}
from
'
vs/base/common/paths
'
;
import
{
Extensions
,
IEditorRegistry
}
from
'
vs/workbench/browser/parts/editor/baseEditor
'
;
import
URI
from
'
vs/base/common/uri
'
;
...
...
@@ -96,10 +98,16 @@ suite('Workbench QuickOpen', () => {
test
(
'
EditorHistoryModel
'
,
()
=>
{
Registry
.
as
(
'
workbench.contributions.editors
'
).
setInstantiationService
(
new
InstantiationService
());
let
services
=
new
ServiceCollection
();
let
eventService
=
new
TestEventService
();
let
editorService
=
new
TestEditorService
();
let
contextService
=
new
TestContextService
();
let
inst
=
new
InstantiationService
(
new
ServiceCollection
([
IWorkbenchEditorService
,
editorService
]));
services
.
set
(
IEventService
,
eventService
);
services
.
set
(
IWorkspaceContextService
,
contextService
);
services
.
set
(
IWorkbenchEditorService
,
editorService
);
let
inst
=
new
InstantiationService
(
services
);
let
model
=
new
EditorHistoryModel
(
editorService
,
inst
,
contextService
);
...
...
@@ -202,13 +210,18 @@ suite('Workbench QuickOpen', () => {
});
test
(
'
QuickOpenController adds to history on editor input change and can handle dispose
'
,
()
=>
{
let
editorService
=
new
TestEditorService
();
let
services
=
new
ServiceCollection
();
let
eventService
=
new
TestEventService
();
let
storageService
=
new
TestStorageService
();
let
eventService
=
new
TestEventService
();
let
editorService
=
new
TestEditorService
();
let
contextService
=
new
TestContextService
();
let
inst
=
new
InstantiationService
(
new
ServiceCollection
([
IWorkbenchEditorService
,
editorService
]));
services
.
set
(
IEventService
,
eventService
);
services
.
set
(
IWorkspaceContextService
,
contextService
);
services
.
set
(
IWorkbenchEditorService
,
editorService
);
let
inst
=
new
InstantiationService
(
services
);
let
controller
=
new
QuickOpenController
(
eventService
,
...
...
@@ -226,7 +239,7 @@ suite('Workbench QuickOpen', () => {
assert
.
equal
(
0
,
controller
.
getEditorHistoryModel
().
getEntries
().
length
);
let
cinput1
=
<
EditorInput
>
inst
.
createInstance
(
fileInputCtor
,
toResource
(
'
Hello World
'
),
'
text/plain
'
,
void
0
);
let
cinput1
=
<
EditorInput
>
inst
.
createInstance
(
fileInputCtor
,
toResource
(
'
Hello World
'
),
'
text/plain
'
,
null
);
let
event
=
new
EditorEvent
(
null
,
''
,
cinput1
,
null
,
Position
.
LEFT
);
eventService
.
emit
(
EventType
.
EDITOR_INPUT_CHANGING
,
event
);
...
...
src/vs/workbench/test/common/editor/editorStacksModel.test.ts
浏览文件 @
c8680b8f
...
...
@@ -101,6 +101,10 @@ class TestEditorInput extends EditorInput {
public
matches
(
other
:
TestEditorInput
):
boolean
{
return
other
&&
this
.
id
===
other
.
id
&&
other
instanceof
TestEditorInput
;
}
public
setDirty
():
void
{
this
.
_onDidChangeDirty
.
fire
();
}
}
class
NonSerializableTestEditorInput
extends
EditorInput
{
...
...
@@ -1608,4 +1612,42 @@ suite('Editor Stacks Model', () => {
assert
.
equal
(
input2
.
isDisposed
(),
true
);
assert
.
equal
(
input1
.
isDisposed
(),
false
);
});
test
(
'
Stack - Multiple Editors - Editor Emits Dirty
'
,
function
()
{
const
model
=
create
();
const
group1
=
model
.
openGroup
(
'
group1
'
);
const
group2
=
model
.
openGroup
(
'
group2
'
);
const
input1
=
input
();
const
input2
=
input
();
group1
.
openEditor
(
input1
,
{
pinned
:
true
,
active
:
true
});
group2
.
openEditor
(
input2
,
{
pinned
:
true
,
active
:
true
});
let
dirtyCounter
=
0
;
model
.
onEditorDirty
(()
=>
{
dirtyCounter
++
;
});
(
<
TestEditorInput
>
input1
).
setDirty
();
assert
.
equal
(
dirtyCounter
,
1
);
(
<
TestEditorInput
>
input2
).
setDirty
();
assert
.
equal
(
dirtyCounter
,
2
);
group2
.
closeAllEditors
();
(
<
TestEditorInput
>
input2
).
setDirty
();
assert
.
equal
(
dirtyCounter
,
2
);
model
.
closeGroups
();
(
<
TestEditorInput
>
input1
).
setDirty
();
assert
.
equal
(
dirtyCounter
,
2
);
});
});
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录