Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
fae8b9b7
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,发现更多精彩内容 >>
提交
fae8b9b7
编写于
11月 21, 2016
作者:
B
Benjamin Pasero
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into ben/hot-exit-restore
上级
a50aefd4
5081a593
变更
21
隐藏空白更改
内联
并排
Showing
21 changed file
with
299 addition
and
129 deletion
+299
-129
src/vs/base/common/async.ts
src/vs/base/common/async.ts
+17
-1
src/vs/base/node/extfs.ts
src/vs/base/node/extfs.ts
+6
-7
src/vs/base/node/pfs.ts
src/vs/base/node/pfs.ts
+37
-9
src/vs/base/parts/quickopen/browser/quickOpenWidget.ts
src/vs/base/parts/quickopen/browser/quickOpenWidget.ts
+6
-2
src/vs/base/test/common/async.test.ts
src/vs/base/test/common/async.test.ts
+26
-0
src/vs/base/test/node/extfs/extfs.test.ts
src/vs/base/test/node/extfs/extfs.test.ts
+1
-1
src/vs/base/test/node/pfs.test.ts
src/vs/base/test/node/pfs.test.ts
+104
-0
src/vs/platform/backup/test/electron-main/backupMainService.test.ts
...tform/backup/test/electron-main/backupMainService.test.ts
+1
-1
src/vs/workbench/browser/parts/quickopen/quickOpenController.ts
.../workbench/browser/parts/quickopen/quickOpenController.ts
+20
-4
src/vs/workbench/electron-browser/actions.ts
src/vs/workbench/electron-browser/actions.ts
+38
-65
src/vs/workbench/electron-browser/common.ts
src/vs/workbench/electron-browser/common.ts
+3
-3
src/vs/workbench/electron-browser/shell.ts
src/vs/workbench/electron-browser/shell.ts
+4
-4
src/vs/workbench/parts/files/browser/fileActions.contribution.ts
...workbench/parts/files/browser/fileActions.contribution.ts
+1
-1
src/vs/workbench/parts/files/browser/fileActions.ts
src/vs/workbench/parts/files/browser/fileActions.ts
+1
-1
src/vs/workbench/parts/files/browser/views/explorerViewer.ts
src/vs/workbench/parts/files/browser/views/explorerViewer.ts
+4
-2
src/vs/workbench/parts/git/electron-browser/gitActions.ts
src/vs/workbench/parts/git/electron-browser/gitActions.ts
+1
-1
src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.ts
.../parts/snippets/electron-browser/snippets.contribution.ts
+2
-12
src/vs/workbench/services/backup/test/backupFileService.test.ts
.../workbench/services/backup/test/backupFileService.test.ts
+1
-1
src/vs/workbench/services/files/node/fileService.ts
src/vs/workbench/services/files/node/fileService.ts
+2
-2
src/vs/workbench/services/history/browser/history.ts
src/vs/workbench/services/history/browser/history.ts
+17
-10
src/vs/workbench/services/textfile/common/textFileEditorModel.ts
...workbench/services/textfile/common/textFileEditorModel.ts
+7
-2
未找到文件。
src/vs/base/common/async.ts
浏览文件 @
fae8b9b7
...
...
@@ -10,6 +10,7 @@ import * as platform from 'vs/base/common/platform';
import
{
Promise
,
TPromise
,
ValueCallback
,
ErrorCallback
,
ProgressCallback
}
from
'
vs/base/common/winjs.base
'
;
import
{
CancellationToken
,
CancellationTokenSource
}
from
'
vs/base/common/cancellation
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
Event
,
{
Emitter
}
from
'
vs/base/common/event
'
;
function
isThenable
<
T
>
(
obj
:
any
):
obj
is
Thenable
<
T
>
{
return
obj
&&
typeof
(
<
Thenable
<
any
>>
obj
).
then
===
'
function
'
;
...
...
@@ -430,11 +431,17 @@ export class Limiter<T> {
private
runningPromises
:
number
;
private
maxDegreeOfParalellism
:
number
;
private
outstandingPromises
:
ILimitedTaskFactory
[];
private
_onFinished
:
Emitter
<
void
>
;
constructor
(
maxDegreeOfParalellism
:
number
)
{
this
.
maxDegreeOfParalellism
=
maxDegreeOfParalellism
;
this
.
outstandingPromises
=
[];
this
.
runningPromises
=
0
;
this
.
_onFinished
=
new
Emitter
<
void
>
();
}
public
get
onFinished
():
Event
<
void
>
{
return
this
.
_onFinished
.
event
;
}
queue
(
promiseFactory
:
ITask
<
Promise
>
):
Promise
;
...
...
@@ -464,7 +471,16 @@ export class Limiter<T> {
private
consumed
():
void
{
this
.
runningPromises
--
;
this
.
consume
();
if
(
this
.
outstandingPromises
.
length
>
0
)
{
this
.
consume
();
}
else
{
this
.
_onFinished
.
fire
();
}
}
public
dispose
():
void
{
this
.
_onFinished
.
dispose
();
}
}
...
...
src/vs/base/node/extfs.ts
浏览文件 @
fae8b9b7
...
...
@@ -5,14 +5,13 @@
'
use strict
'
;
import
uuid
=
require
(
'
vs/base/common/uuid
'
);
import
strings
=
require
(
'
vs/base/common/strings
'
);
import
platform
=
require
(
'
vs/base/common/platform
'
);
import
*
as
uuid
from
'
vs/base/common/uuid
'
;
import
*
as
strings
from
'
vs/base/common/strings
'
;
import
*
as
platform
from
'
vs/base/common/platform
'
;
import
*
as
flow
from
'
vs/base/node/flow
'
;
import
flow
=
require
(
'
vs/base/node/flow
'
);
import
fs
=
require
(
'
fs
'
);
import
paths
=
require
(
'
path
'
);
import
*
as
fs
from
'
fs
'
;
import
*
as
paths
from
'
path
'
;
const
loop
=
flow
.
loop
;
...
...
src/vs/base/node/pfs.ts
浏览文件 @
fae8b9b7
...
...
@@ -6,11 +6,13 @@
'
use strict
'
;
import
{
Promise
,
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
extfs
=
require
(
'
vs/base/node/extfs
'
)
;
import
paths
=
require
(
'
vs/base/common/paths
'
)
;
import
*
as
extfs
from
'
vs/base/node/extfs
'
;
import
*
as
paths
from
'
vs/base/common/paths
'
;
import
{
dirname
,
join
}
from
'
path
'
;
import
{
nfcall
}
from
'
vs/base/common/async
'
;
import
fs
=
require
(
'
fs
'
);
import
{
nfcall
,
Queue
}
from
'
vs/base/common/async
'
;
import
*
as
fs
from
'
fs
'
;
import
*
as
platform
from
'
vs/base/common/platform
'
;
import
{
once
}
from
'
vs/base/common/event
'
;
export
function
readdir
(
path
:
string
):
TPromise
<
string
[]
>
{
return
nfcall
(
extfs
.
readdir
,
path
);
...
...
@@ -113,16 +115,42 @@ export function readFile(path: string, encoding?: string): TPromise<Buffer | str
return
nfcall
(
fs
.
readFile
,
path
,
encoding
);
}
// According to node.js docs (https://nodejs.org/docs/v6.5.0/api/fs.html#fs_fs_writefile_file_data_options_callback)
// it is not safe to call writeFile() on the same path multiple times without waiting for the callback to return.
// Therefor we use a Queue on the path that is given to us to sequentialize calls to the same path properly.
const
writeFilePathQueue
:
{
[
path
:
string
]:
Queue
<
void
>
}
=
Object
.
create
(
null
);
export
function
writeFile
(
path
:
string
,
data
:
string
,
encoding
?:
string
):
TPromise
<
void
>
;
export
function
writeFile
(
path
:
string
,
data
:
NodeBuffer
,
encoding
?:
string
):
TPromise
<
void
>
;
export
function
writeFile
(
path
:
string
,
data
:
any
,
encoding
:
string
=
'
utf8
'
):
TPromise
<
void
>
{
return
nfcall
(
fs
.
writeFile
,
path
,
data
,
encoding
);
let
queueKey
=
toQueueKey
(
path
);
return
ensureWriteFileQueue
(
queueKey
).
queue
(()
=>
nfcall
(
extfs
.
writeFileAndFlush
,
path
,
data
,
encoding
));
}
function
toQueueKey
(
path
:
string
):
string
{
let
queueKey
=
path
;
if
(
platform
.
isWindows
||
platform
.
isMacintosh
)
{
queueKey
=
queueKey
.
toLowerCase
();
// accomodate for case insensitive file systems
}
return
queueKey
;
}
export
function
writeFileAndFlush
(
path
:
string
,
data
:
string
,
encoding
?:
string
):
TPromise
<
void
>
;
export
function
writeFileAndFlush
(
path
:
string
,
data
:
NodeBuffer
,
encoding
?:
string
):
TPromise
<
void
>
;
export
function
writeFileAndFlush
(
path
:
string
,
data
:
any
,
encoding
:
string
=
'
utf8
'
):
TPromise
<
void
>
{
return
nfcall
(
extfs
.
writeFileAndFlush
,
path
,
data
,
encoding
);
function
ensureWriteFileQueue
(
queueKey
:
string
):
Queue
<
void
>
{
let
writeFileQueue
=
writeFilePathQueue
[
queueKey
];
if
(
!
writeFileQueue
)
{
writeFileQueue
=
new
Queue
<
void
>
();
writeFilePathQueue
[
queueKey
]
=
writeFileQueue
;
const
onFinish
=
once
(
writeFileQueue
.
onFinished
);
onFinish
(()
=>
{
delete
writeFilePathQueue
[
queueKey
];
writeFileQueue
.
dispose
();
});
}
return
writeFileQueue
;
}
/**
...
...
src/vs/base/parts/quickopen/browser/quickOpenWidget.ts
浏览文件 @
fae8b9b7
...
...
@@ -561,7 +561,7 @@ export class QuickOpenWidget implements IModelProvider {
const
entryToFocus
=
caseSensitiveMatch
||
caseInsensitiveMatch
;
if
(
entryToFocus
)
{
this
.
tree
.
setFocus
(
entryToFocus
);
this
.
tree
.
reveal
(
entryToFocus
,
0
).
done
(
null
,
errors
.
onUnexpectedError
);
this
.
tree
.
reveal
(
entryToFocus
,
0
.5
).
done
(
null
,
errors
.
onUnexpectedError
);
return
;
}
...
...
@@ -570,7 +570,7 @@ export class QuickOpenWidget implements IModelProvider {
// Second check for auto focus of first entry
if
(
autoFocus
.
autoFocusFirstEntry
)
{
this
.
tree
.
focusFirst
();
this
.
tree
.
reveal
(
this
.
tree
.
getFocus
()
,
0
).
done
(
null
,
errors
.
onUnexpectedError
);
this
.
tree
.
reveal
(
this
.
tree
.
getFocus
()).
done
(
null
,
errors
.
onUnexpectedError
);
}
// Third check for specific index option
...
...
@@ -798,6 +798,10 @@ export class QuickOpenWidget implements IModelProvider {
return
this
.
progressBar
;
}
public
getInputBox
():
InputBox
{
return
this
.
inputBox
;
}
public
setExtraClass
(
clazz
:
string
):
void
{
const
previousClass
=
this
.
builder
.
getProperty
(
'
extra-class
'
);
if
(
previousClass
)
{
...
...
src/vs/base/test/common/async.test.ts
浏览文件 @
fae8b9b7
...
...
@@ -543,4 +543,30 @@ suite('Async', () => {
});
});
});
test
(
'
Queue - events
'
,
function
(
done
)
{
let
queue
=
new
Async
.
Queue
();
let
finished
=
false
;
queue
.
onFinished
(()
=>
{
done
();
});
let
res
=
[];
let
f1
=
()
=>
TPromise
.
timeout
(
10
).
then
(()
=>
res
.
push
(
2
));
let
f2
=
()
=>
TPromise
.
timeout
(
20
).
then
(()
=>
res
.
push
(
4
));
let
f3
=
()
=>
TPromise
.
timeout
(
0
).
then
(()
=>
res
.
push
(
5
));
const
q1
=
queue
.
queue
(
f1
);
const
q2
=
queue
.
queue
(
f2
);
queue
.
queue
(
f3
);
q1
.
then
(()
=>
{
assert
.
ok
(
!
finished
);
q2
.
then
(()
=>
{
assert
.
ok
(
!
finished
);
});
});
});
});
src/vs/base/test/node/extfs/extfs.test.ts
浏览文件 @
fae8b9b7
...
...
@@ -144,7 +144,7 @@ suite('Extfs', () => {
assert
.
equal
(
fs
.
readFileSync
(
testFile
),
largeString
);
done
(
);
extfs
.
del
(
parentDir
,
os
.
tmpdir
(),
()
=>
{
},
done
);
});
});
});
...
...
src/vs/base/test/node/pfs.test.ts
0 → 100644
浏览文件 @
fae8b9b7
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
assert
=
require
(
'
assert
'
);
import
os
=
require
(
'
os
'
);
import
path
=
require
(
'
path
'
);
import
fs
=
require
(
'
fs
'
);
import
uuid
=
require
(
'
vs/base/common/uuid
'
);
import
extfs
=
require
(
'
vs/base/node/extfs
'
);
import
{
onError
}
from
'
vs/test/utils/servicesTestUtils
'
;
import
*
as
pfs
from
'
vs/base/node/pfs
'
;
suite
(
'
PFS
'
,
()
=>
{
test
(
'
writeFile
'
,
function
(
done
:
()
=>
void
)
{
const
id
=
uuid
.
generateUuid
();
const
parentDir
=
path
.
join
(
os
.
tmpdir
(),
'
vsctests
'
,
id
);
const
newDir
=
path
.
join
(
parentDir
,
'
pfs
'
,
id
);
const
testFile
=
path
.
join
(
newDir
,
'
writefile.txt
'
);
extfs
.
mkdirp
(
newDir
,
493
,
(
error
)
=>
{
if
(
error
)
{
return
onError
(
error
,
done
);
}
assert
.
ok
(
fs
.
existsSync
(
newDir
));
pfs
.
writeFile
(
testFile
,
'
Hello World
'
,
null
).
done
(()
=>
{
assert
.
equal
(
fs
.
readFileSync
(
testFile
),
'
Hello World
'
);
extfs
.
del
(
parentDir
,
os
.
tmpdir
(),
()
=>
{
},
done
);
},
error
=>
onError
(
error
,
done
));
});
});
test
(
'
writeFile - parallel write on different files works
'
,
function
(
done
:
()
=>
void
)
{
const
id
=
uuid
.
generateUuid
();
const
parentDir
=
path
.
join
(
os
.
tmpdir
(),
'
vsctests
'
,
id
);
const
newDir
=
path
.
join
(
parentDir
,
'
pfs
'
,
id
);
const
testFile1
=
path
.
join
(
newDir
,
'
writefile1.txt
'
);
const
testFile2
=
path
.
join
(
newDir
,
'
writefile2.txt
'
);
const
testFile3
=
path
.
join
(
newDir
,
'
writefile3.txt
'
);
const
testFile4
=
path
.
join
(
newDir
,
'
writefile4.txt
'
);
const
testFile5
=
path
.
join
(
newDir
,
'
writefile5.txt
'
);
extfs
.
mkdirp
(
newDir
,
493
,
(
error
)
=>
{
if
(
error
)
{
return
onError
(
error
,
done
);
}
assert
.
ok
(
fs
.
existsSync
(
newDir
));
TPromise
.
join
([
pfs
.
writeFile
(
testFile1
,
'
Hello World 1
'
,
null
),
pfs
.
writeFile
(
testFile2
,
'
Hello World 2
'
,
null
),
pfs
.
writeFile
(
testFile3
,
'
Hello World 3
'
,
null
),
pfs
.
writeFile
(
testFile4
,
'
Hello World 4
'
,
null
),
pfs
.
writeFile
(
testFile5
,
'
Hello World 5
'
,
null
)
]).
done
(()
=>
{
assert
.
equal
(
fs
.
readFileSync
(
testFile1
),
'
Hello World 1
'
);
assert
.
equal
(
fs
.
readFileSync
(
testFile2
),
'
Hello World 2
'
);
assert
.
equal
(
fs
.
readFileSync
(
testFile3
),
'
Hello World 3
'
);
assert
.
equal
(
fs
.
readFileSync
(
testFile4
),
'
Hello World 4
'
);
assert
.
equal
(
fs
.
readFileSync
(
testFile5
),
'
Hello World 5
'
);
extfs
.
del
(
parentDir
,
os
.
tmpdir
(),
()
=>
{
},
done
);
},
error
=>
onError
(
error
,
done
));
});
});
test
(
'
writeFile - parallel write on same files works and is sequentalized
'
,
function
(
done
:
()
=>
void
)
{
const
id
=
uuid
.
generateUuid
();
const
parentDir
=
path
.
join
(
os
.
tmpdir
(),
'
vsctests
'
,
id
);
const
newDir
=
path
.
join
(
parentDir
,
'
pfs
'
,
id
);
const
testFile
=
path
.
join
(
newDir
,
'
writefile.txt
'
);
extfs
.
mkdirp
(
newDir
,
493
,
(
error
)
=>
{
if
(
error
)
{
return
onError
(
error
,
done
);
}
assert
.
ok
(
fs
.
existsSync
(
newDir
));
TPromise
.
join
([
pfs
.
writeFile
(
testFile
,
'
Hello World 1
'
,
null
),
pfs
.
writeFile
(
testFile
,
'
Hello World 2
'
,
null
),
TPromise
.
timeout
(
10
).
then
(()
=>
pfs
.
writeFile
(
testFile
,
'
Hello World 3
'
,
null
)),
pfs
.
writeFile
(
testFile
,
'
Hello World 4
'
,
null
),
TPromise
.
timeout
(
10
).
then
(()
=>
pfs
.
writeFile
(
testFile
,
'
Hello World 5
'
,
null
))
]).
done
(()
=>
{
assert
.
equal
(
fs
.
readFileSync
(
testFile
),
'
Hello World 5
'
);
extfs
.
del
(
parentDir
,
os
.
tmpdir
(),
()
=>
{
},
done
);
},
error
=>
onError
(
error
,
done
));
});
});
});
\ No newline at end of file
src/vs/platform/backup/test/electron-main/backupMainService.test.ts
浏览文件 @
fae8b9b7
...
...
@@ -113,7 +113,7 @@ suite('BackupMainService', () => {
test
(
'
removeWorkspaceBackupPath should fail gracefully when removing a path that doesn
\'
t exist
'
,
done
=>
{
const
workspacesJson
:
IBackupWorkspacesFormat
=
{
folderWorkspaces
:
[
fooFile
.
fsPath
]
};
pfs
.
writeFile
AndFlush
(
backupWorkspacesPath
,
JSON
.
stringify
(
workspacesJson
)).
then
(()
=>
{
pfs
.
writeFile
(
backupWorkspacesPath
,
JSON
.
stringify
(
workspacesJson
)).
then
(()
=>
{
service
.
removeWorkspaceBackupPathSync
(
barFile
);
pfs
.
readFile
(
backupWorkspacesPath
,
'
utf-8
'
).
then
(
content
=>
{
const
json
=
<
IBackupWorkspacesFormat
>
JSON
.
parse
(
content
);
...
...
src/vs/workbench/browser/parts/quickopen/quickOpenController.ts
浏览文件 @
fae8b9b7
...
...
@@ -310,6 +310,14 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe
this
.
pickOpenWidget
.
layout
(
this
.
layoutDimensions
);
}
// Detect cancellation while pick promise is loading
let
cancelTriggered
=
false
;
this
.
pickOpenWidget
.
setCallbacks
({
onOk
:
()
=>
{
/* ignore, handle later */
},
onCancel
:
()
=>
{
cancelTriggered
=
true
;
},
onType
:
(
value
:
string
)
=>
{
/* ignore, handle later */
},
});
return
new
TPromise
<
IPickOpenEntry
|
string
>
((
complete
,
error
,
progress
)
=>
{
// hide widget when being cancelled
...
...
@@ -323,8 +331,8 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe
// Resolve picks
picksPromise
.
then
(
picks
=>
{
if
(
this
.
currentPickerToken
!==
currentPickerToken
)
{
return
;
// Return if another request came after
if
(
this
.
currentPickerToken
!==
currentPickerToken
||
cancelTriggered
)
{
return
complete
(
void
0
);
// Return as canceled if another request came after or user canceled
}
picksPromiseDone
=
true
;
...
...
@@ -342,7 +350,7 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe
model
.
setEntries
(
entries
);
// Handlers
this
.
pickOpenWidget
.
setCallbacks
(
{
const
callbacks
=
{
onOk
:
()
=>
{
if
(
picks
.
length
===
0
)
{
return
complete
(
null
);
...
...
@@ -410,7 +418,8 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe
},
onShow
:
()
=>
this
.
handleOnShow
(
true
),
onHide
:
(
reason
)
=>
this
.
handleOnHide
(
true
,
reason
)
});
};
this
.
pickOpenWidget
.
setCallbacks
(
callbacks
);
// Set input
if
(
!
this
.
pickOpenWidget
.
isVisible
())
{
...
...
@@ -418,6 +427,13 @@ export class QuickOpenController extends WorkbenchComponent implements IQuickOpe
}
else
{
this
.
pickOpenWidget
.
setInput
(
model
,
autoFocus
);
}
// The user might have typed something (or options.value was set) so we need to play back
// the input box value through our callbacks to filter the result accordingly.
const
inputValue
=
this
.
pickOpenWidget
.
getInputBox
().
value
;
if
(
inputValue
)
{
callbacks
.
onType
(
inputValue
);
}
},
(
err
)
=>
{
this
.
pickOpenWidget
.
hide
();
...
...
src/vs/workbench/electron-browser/actions.ts
浏览文件 @
fae8b9b7
...
...
@@ -7,7 +7,6 @@
import
URI
from
'
vs/base/common/uri
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
timer
=
require
(
'
vs/base/common/timer
'
);
import
{
Action
}
from
'
vs/base/common/actions
'
;
import
{
IWindowIPCService
}
from
'
vs/workbench/services/window/electron-browser/windowService
'
;
import
{
IWindowService
,
IWindowsService
}
from
'
vs/platform/windows/common/windows
'
;
...
...
@@ -331,7 +330,6 @@ export class ShowStartupPerformance extends Action {
}
public
run
():
TPromise
<
boolean
>
{
const
perfTable
=
this
.
environmentService
.
performance
?
this
.
getPerformanceTable
()
:
this
.
getFingerprintTable
();
// Show dev tools
this
.
windowService
.
openDevTools
();
...
...
@@ -346,81 +344,55 @@ export class ShowStartupPerformance extends Action {
console
.
log
(
`Initial Startup:
${
fingerprint
.
initialStartup
}
`
);
console
.
log
(
`Screen Reader Active:
${
fingerprint
.
hasAccessibilitySupport
}
`
);
console
.
log
(
`Empty Workspace:
${
fingerprint
.
emptyWorkbench
}
`
);
(
<
any
>
console
).
table
(
perfTable
);
let
nodeModuleLoadTime
:
number
;
let
nodeModuleLoadDetails
:
any
[];
if
(
this
.
environmentService
.
performance
)
{
const
nodeModuleTimes
=
this
.
analyzeNodeModulesLoadTimes
();
nodeModuleLoadTime
=
nodeModuleTimes
.
duration
;
nodeModuleLoadDetails
=
nodeModuleTimes
.
table
;
}
(
<
any
>
console
).
table
(
this
.
getFingerprintTable
(
nodeModuleLoadTime
));
if
(
nodeModuleLoadDetails
)
{
(
<
any
>
console
).
groupCollapsed
(
'
node_modules Load Details
'
);
(
<
any
>
console
).
table
(
nodeModuleLoadDetails
);
(
<
any
>
console
).
groupEnd
();
}
(
<
any
>
console
).
groupEnd
();
},
1000
);
return
TPromise
.
as
(
true
);
}
private
getFingerprintTable
():
any
[]
{
private
getFingerprintTable
(
nodeModuleLoadTime
?:
number
):
any
[]
{
const
table
:
any
[]
=
[];
const
fingerprint
:
IStartupFingerprint
=
timers
.
fingerprint
;
if
(
fingerprint
.
initialStartup
)
{
table
.
push
({
Topic
:
'
[main]
initial start => begin to require(workbench.main.js)
'
,
'
Took (ms)
'
:
fingerprint
.
timers
.
ellapsedMain
});
table
.
push
({
Topic
:
'
[main]
start => window.loadUrl()
'
,
'
Took (ms)
'
:
fingerprint
.
timers
.
ellapsedWindowLoad
});
}
table
.
push
({
Topic
:
'
[renderer] window.loadUrl() => begin to require(workbench.main.js)
'
,
'
Took (ms)
'
:
fingerprint
.
timers
.
ellapsedWindowLoadToRequire
});
table
.
push
({
Topic
:
'
[renderer] require(workbench.main.js)
'
,
'
Took (ms)
'
:
fingerprint
.
timers
.
ellapsedRequire
});
if
(
nodeModuleLoadTime
)
{
table
.
push
({
Topic
:
'
[renderer] -> of which require() node_modules
'
,
'
Took (ms)
'
:
nodeModuleLoadTime
});
}
table
.
push
({
Topic
:
'
[renderer] create extension host => extensions onReady()
'
,
'
Took (ms)
'
:
fingerprint
.
timers
.
ellapsedExtensions
});
table
.
push
({
Topic
:
'
[renderer] restore viewlet
'
,
'
Took (ms)
'
:
fingerprint
.
timers
.
ellapsedViewletRestore
});
table
.
push
({
Topic
:
'
[renderer] restor
ing
editor view state
'
,
'
Took (ms)
'
:
fingerprint
.
timers
.
ellapsedEditorRestore
});
table
.
push
({
Topic
:
'
[renderer] restor
e
editor view state
'
,
'
Took (ms)
'
:
fingerprint
.
timers
.
ellapsedEditorRestore
});
table
.
push
({
Topic
:
'
[renderer] overall workbench load
'
,
'
Took (ms)
'
:
fingerprint
.
timers
.
ellapsedWorkbench
});
table
.
push
({
Topic
:
'
------------------------------------------------------
'
});
if
(
fingerprint
.
initialStartup
)
{
table
.
push
({
Topic
:
'
[main] load window at
'
,
'
Start (ms)
'
:
fingerprint
.
timers
.
windowLoad
});
}
table
.
push
({
Topic
:
'
[main, renderer] start => extensions ready
'
,
'
Took (ms)
'
:
fingerprint
.
timers
.
extensionsReady
});
table
.
push
({
Topic
:
'
[main, renderer] start => extensions ready
'
,
'
Took (ms)
'
:
fingerprint
.
timers
.
ellapsedExtensionsReady
});
table
.
push
({
Topic
:
'
[main, renderer] start => workbench ready
'
,
'
Took (ms)
'
:
fingerprint
.
ellapsed
});
return
table
;
}
private
getPerformanceTable
():
any
[]
{
const
table
:
any
[]
=
[];
table
.
push
(...
this
.
analyzeLoaderTimes
());
const
start
=
Math
.
round
(
timers
.
isInitialStartup
?
timers
.
perfStartTime
:
timers
.
perfWindowLoadTime
);
let
lastEvent
:
timer
.
ITimerEvent
;
const
events
=
timer
.
getTimeKeeper
().
getCollectedEvents
();
events
.
forEach
((
e
)
=>
{
if
(
e
.
topic
===
'
Startup
'
)
{
lastEvent
=
e
;
const
entry
:
any
=
{};
entry
[
'
Event
'
]
=
e
.
name
;
entry
[
'
Took (ms)
'
]
=
e
.
stopTime
.
getTime
()
-
e
.
startTime
.
getTime
();
entry
[
'
Start (ms)
'
]
=
Math
.
max
(
e
.
startTime
.
getTime
()
-
start
,
0
);
entry
[
'
End (ms)
'
]
=
e
.
stopTime
.
getTime
()
-
start
;
table
.
push
(
entry
);
}
});
table
.
push
({
Event
:
'
------------------------------------------------------
'
});
if
(
timers
.
isInitialStartup
)
{
const
loadWindow
=
Math
.
round
(
timers
.
perfWindowLoadTime
);
const
windowLoadEvent
:
any
=
{};
windowLoadEvent
[
'
Event
'
]
=
'
[main] load window at
'
;
windowLoadEvent
[
'
Start (ms)
'
]
=
loadWindow
-
start
;
table
.
push
(
windowLoadEvent
);
}
const
totalExtensions
:
any
=
{};
totalExtensions
[
'
Event
'
]
=
'
[main, renderer] start => extensions ready
'
;
totalExtensions
[
'
Took (ms)
'
]
=
timers
.
perfAfterExtensionLoad
-
start
;
table
.
push
(
totalExtensions
);
const
totalWorkbench
:
any
=
{};
totalWorkbench
[
'
Event
'
]
=
'
[main, renderer] start => workbench ready
'
;
totalWorkbench
[
'
Took (ms)
'
]
=
timers
.
workbenchStarted
-
start
;
table
.
push
(
totalWorkbench
);
return
table
;
}
private
analyzeLoaderTimes
():
any
[]
{
private
analyzeNodeModulesLoadTimes
():
{
table
:
any
[],
duration
:
number
}
{
const
stats
=
<
ILoaderEvent
[]
>
(
<
any
>
require
).
getStats
();
const
result
=
[];
...
...
@@ -430,28 +402,29 @@ export class ShowStartupPerformance extends Action {
if
(
stats
[
i
].
type
===
LoaderEventType
.
NodeEndNativeRequire
)
{
if
(
stats
[
i
-
1
].
type
===
LoaderEventType
.
NodeBeginNativeRequire
&&
stats
[
i
-
1
].
detail
===
stats
[
i
].
detail
)
{
const
entry
:
any
=
{};
const
dur
=
(
stats
[
i
].
timestamp
-
stats
[
i
-
1
].
timestamp
);
entry
[
'
Event
'
]
=
'
nodeRequire
'
+
stats
[
i
].
detail
;
entry
[
'
Took (ms)
'
]
=
(
stats
[
i
].
timestamp
-
stats
[
i
-
1
].
timestamp
);
total
+=
(
stats
[
i
].
timestamp
-
stats
[
i
-
1
].
timestamp
)
;
entry
[
'
Start (ms)
'
]
=
'
**
'
+
stats
[
i
-
1
].
timestamp
;
entry
[
'
End (ms)
'
]
=
'
**
'
+
stats
[
i
-
1
].
timestamp
;
entry
[
'
Took (ms)
'
]
=
dur
.
toFixed
(
2
);
total
+=
dur
;
entry
[
'
Start (ms)
'
]
=
'
**
'
+
stats
[
i
-
1
].
timestamp
.
toFixed
(
2
)
;
entry
[
'
End (ms)
'
]
=
'
**
'
+
stats
[
i
-
1
].
timestamp
.
toFixed
(
2
)
;
result
.
push
(
entry
);
}
}
}
if
(
total
>
0
)
{
result
.
push
({
Event
:
'
------------------------------------------------------
'
});
const
entry
:
any
=
{};
entry
[
'
Event
'
]
=
'
[renderer] total require() node
modules
'
;
entry
[
'
Took (ms)
'
]
=
total
;
entry
[
'
Event
'
]
=
'
[renderer] total require() node
_
modules
'
;
entry
[
'
Took (ms)
'
]
=
total
.
toFixed
(
2
)
;
entry
[
'
Start (ms)
'
]
=
'
**
'
;
entry
[
'
End (ms)
'
]
=
'
**
'
;
result
.
push
(
entry
);
result
.
push
({
Event
:
'
------------------------------------------------------
'
});
}
return
result
;
return
{
table
:
result
,
duration
:
Math
.
round
(
total
)
}
;
}
}
...
...
src/vs/workbench/electron-browser/common.ts
浏览文件 @
fae8b9b7
...
...
@@ -24,10 +24,10 @@ export interface IWindowConfiguration {
export
interface
IStartupFingerprint
{
ellapsed
:
number
;
timers
:
{
ellapsed
Main
?:
number
;
windowLoad
?
:
number
;
ellapsed
WindowLoad
?:
number
;
ellapsedWindowLoadToRequire
:
number
;
ellapsedExtensions
:
number
;
extensionsReady
:
number
;
e
llapsedE
xtensionsReady
:
number
;
ellapsedRequire
:
number
;
ellapsedViewletRestore
:
number
;
ellapsedEditorRestore
:
number
;
...
...
src/vs/workbench/electron-browser/shell.ts
浏览文件 @
fae8b9b7
...
...
@@ -238,11 +238,12 @@ export class WorkbenchShell {
ellapsed
:
Math
.
round
(
workbenchStarted
-
start
),
timers
:
{
ellapsedExtensions
:
Math
.
round
(
timers
.
perfAfterExtensionLoad
-
timers
.
perfBeforeExtensionLoad
),
extensionsReady
:
Math
.
round
(
timers
.
perfAfterExtensionLoad
-
start
),
e
llapsedE
xtensionsReady
:
Math
.
round
(
timers
.
perfAfterExtensionLoad
-
start
),
ellapsedRequire
:
Math
.
round
(
timers
.
perfAfterLoadWorkbenchMain
-
timers
.
perfBeforeLoadWorkbenchMain
),
ellapsedViewletRestore
:
Math
.
round
(
restoreViewletDuration
),
ellapsedEditorRestore
:
Math
.
round
(
restoreEditorsDuration
),
ellapsedWorkbench
:
Math
.
round
(
workbenchStarted
-
timers
.
perfBeforeWorkbenchOpen
)
ellapsedWorkbench
:
Math
.
round
(
workbenchStarted
-
timers
.
perfBeforeWorkbenchOpen
),
ellapsedWindowLoadToRequire
:
Math
.
round
(
timers
.
perfBeforeLoadWorkbenchMain
-
timers
.
perfWindowLoadTime
)
},
platform
,
release
,
...
...
@@ -255,8 +256,7 @@ export class WorkbenchShell {
};
if
(
initialStartup
)
{
startupTimeEvent
.
timers
.
ellapsedMain
=
Math
.
round
(
timers
.
perfBeforeLoadWorkbenchMain
-
timers
.
perfStartTime
);
startupTimeEvent
.
timers
.
windowLoad
=
Math
.
round
(
timers
.
perfWindowLoadTime
-
timers
.
perfStartTime
);
startupTimeEvent
.
timers
.
ellapsedWindowLoad
=
Math
.
round
(
timers
.
perfWindowLoadTime
-
timers
.
perfStartTime
);
}
this
.
telemetryService
.
publicLog
(
'
startupTime
'
,
startupTimeEvent
);
...
...
src/vs/workbench/parts/files/browser/fileActions.contribution.ts
浏览文件 @
fae8b9b7
...
...
@@ -123,7 +123,7 @@ class FilesViewerActionContributor extends ActionBarContributor {
if
(
context
&&
context
.
element
instanceof
FileStat
)
{
// Any other item with keybinding
const
keybinding
=
keybindingForAction
(
action
.
id
);
const
keybinding
=
keybindingForAction
(
action
.
id
,
this
.
keybindingService
);
if
(
keybinding
)
{
return
new
ActionItem
(
context
,
action
,
{
label
:
true
,
keybinding
:
this
.
keybindingService
.
getLabelFor
(
keybinding
)
});
}
...
...
src/vs/workbench/parts/files/browser/fileActions.ts
浏览文件 @
fae8b9b7
...
...
@@ -1859,7 +1859,7 @@ export class RefreshExplorerView extends Action {
}
}
export
function
keybindingForAction
(
id
:
string
,
keybindingService
?
:
IKeybindingService
):
Keybinding
{
export
function
keybindingForAction
(
id
:
string
,
keybindingService
:
IKeybindingService
):
Keybinding
{
switch
(
id
)
{
case
GlobalNewUntitledFileAction
.
ID
:
return
new
Keybinding
(
KeyMod
.
CtrlCmd
|
KeyCode
.
KEY_N
);
...
...
src/vs/workbench/parts/files/browser/views/explorerViewer.ts
浏览文件 @
fae8b9b7
...
...
@@ -34,6 +34,7 @@ import { ClickBehavior, DefaultController } from 'vs/base/parts/tree/browser/tre
import
{
ActionsRenderer
}
from
'
vs/base/parts/tree/browser/actionsRenderer
'
;
import
{
FileStat
,
NewStatPlaceholder
}
from
'
vs/workbench/parts/files/common/explorerViewModel
'
;
import
{
DragMouseEvent
,
IMouseEvent
}
from
'
vs/base/browser/mouseEvent
'
;
import
{
IKeybindingService
}
from
'
vs/platform/keybinding/common/keybinding
'
;
import
{
IWorkbenchEditorService
}
from
'
vs/workbench/services/editor/common/editorService
'
;
import
{
IPartService
}
from
'
vs/workbench/services/part/common/partService
'
;
import
{
IWorkspace
,
IWorkspaceContextService
}
from
'
vs/platform/workspace/common/workspace
'
;
...
...
@@ -389,7 +390,8 @@ export class FileController extends DefaultController {
@
ITelemetryService
private
telemetryService
:
ITelemetryService
,
@
IWorkspaceContextService
contextService
:
IWorkspaceContextService
,
@
IMenuService
menuService
:
IMenuService
,
@
IContextKeyService
contextKeyService
:
IContextKeyService
@
IContextKeyService
contextKeyService
:
IContextKeyService
,
@
IKeybindingService
private
keybindingService
:
IKeybindingService
)
{
super
({
clickBehavior
:
ClickBehavior
.
ON_MOUSE_UP
/* do not change to not break DND */
});
...
...
@@ -510,7 +512,7 @@ export class FileController extends DefaultController {
});
},
getActionItem
:
this
.
state
.
actionProvider
.
getActionItem
.
bind
(
this
.
state
.
actionProvider
,
tree
,
stat
),
getKeyBinding
:
(
a
):
Keybinding
=>
keybindingForAction
(
a
.
id
),
getKeyBinding
:
(
a
):
Keybinding
=>
keybindingForAction
(
a
.
id
,
this
.
keybindingService
),
getActionsContext
:
(
event
)
=>
{
return
{
viewletState
:
this
.
state
,
...
...
src/vs/workbench/parts/git/electron-browser/gitActions.ts
浏览文件 @
fae8b9b7
...
...
@@ -42,7 +42,7 @@ export class CloneAction extends Action {
const
result
=
dialog
.
showOpenDialog
(
remote
.
getCurrentWindow
(),
{
title
:
localize
(
'
directory
'
,
"
Destination clone directory
"
),
properties
:
[
'
openDirectory
'
]
properties
:
[
'
openDirectory
'
,
'
createDirectory
'
]
});
if
(
!
result
||
result
.
length
===
0
)
{
...
...
src/vs/workbench/parts/snippets/electron-browser/snippets.contribution.ts
浏览文件 @
fae8b9b7
...
...
@@ -13,6 +13,7 @@ import platform = require('vs/platform/platform');
import
workbenchActionRegistry
=
require
(
'
vs/workbench/common/actionRegistry
'
);
import
workbenchContributions
=
require
(
'
vs/workbench/common/contributions
'
);
import
snippetsTracker
=
require
(
'
./snippetsTracker
'
);
import
*
as
pfs
from
'
vs/base/node/pfs
'
;
import
errors
=
require
(
'
vs/base/common/errors
'
);
import
{
IQuickOpenService
,
IPickOpenEntry
}
from
'
vs/workbench/services/quickopen/common/quickOpenService
'
;
import
{
IEnvironmentService
}
from
'
vs/platform/environment/common/environment
'
;
...
...
@@ -81,7 +82,7 @@ class OpenSnippetsAction extends actions.Action {
'
*/
'
,
'
}
'
].
join
(
'
\n
'
);
return
crea
teFile
(
snippetPath
,
defaultContent
).
then
(()
=>
{
return
pfs
.
wri
teFile
(
snippetPath
,
defaultContent
).
then
(()
=>
{
return
this
.
openFile
(
snippetPath
);
},
(
err
)
=>
{
errors
.
onUnexpectedError
(
nls
.
localize
(
'
openSnippet.errorOnCreate
'
,
'
Unable to create {0}
'
,
snippetPath
));
...
...
@@ -109,17 +110,6 @@ function fileExists(path: string): winjs.TPromise<boolean> {
});
}
function
createFile
(
path
:
string
,
content
:
string
):
winjs
.
Promise
{
return
new
winjs
.
Promise
((
c
,
e
,
p
)
=>
{
fs
.
writeFile
(
path
,
content
,
function
(
err
)
{
if
(
err
)
{
e
(
err
);
}
c
(
true
);
});
});
}
var
preferencesCategory
=
nls
.
localize
(
'
preferences
'
,
"
Preferences
"
);
var
workbenchActionsRegistry
=
<
workbenchActionRegistry
.
IWorkbenchActionRegistry
>
platform
.
Registry
.
as
(
workbenchActionRegistry
.
Extensions
.
WorkbenchActions
);
...
...
src/vs/workbench/services/backup/test/backupFileService.test.ts
浏览文件 @
fae8b9b7
...
...
@@ -50,7 +50,7 @@ suite('BackupFileService', () => {
// Delete any existing backups completely and then re-create it.
extfs
.
del
(
backupHome
,
os
.
tmpdir
(),
()
=>
{
pfs
.
mkdirp
(
backupHome
).
then
(()
=>
{
pfs
.
writeFile
AndFlush
(
workspacesJsonPath
,
''
).
then
(()
=>
{
pfs
.
writeFile
(
workspacesJsonPath
,
''
).
then
(()
=>
{
done
();
});
});
...
...
src/vs/workbench/services/files/node/fileService.ts
浏览文件 @
fae8b9b7
...
...
@@ -275,13 +275,13 @@ export class FileService implements IFileService {
// Write fast if we do UTF 8 without BOM
if
(
!
addBom
&&
encodingToWrite
===
encoding
.
UTF8
)
{
writeFilePromise
=
pfs
.
writeFile
AndFlush
(
absolutePath
,
value
,
encoding
.
UTF8
);
writeFilePromise
=
pfs
.
writeFile
(
absolutePath
,
value
,
encoding
.
UTF8
);
}
// Otherwise use encoding lib
else
{
const
encoded
=
encoding
.
encode
(
value
,
encodingToWrite
,
{
addBOM
:
addBom
});
writeFilePromise
=
pfs
.
writeFile
AndFlush
(
absolutePath
,
encoded
);
writeFilePromise
=
pfs
.
writeFile
(
absolutePath
,
encoded
);
}
// 4.) set contents
...
...
src/vs/workbench/services/history/browser/history.ts
浏览文件 @
fae8b9b7
...
...
@@ -255,6 +255,7 @@ export abstract class BaseHistoryService {
interface
IStackEntry
{
input
:
IEditorInput
|
IResourceInput
;
options
?:
ITextEditorOptions
;
timestamp
:
number
;
}
interface
IRecentlyClosedFile
{
...
...
@@ -270,6 +271,7 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic
private
static
MAX_HISTORY_ITEMS
=
200
;
private
static
MAX_STACK_ITEMS
=
20
;
private
static
MAX_RECENTLY_CLOSED_EDITORS
=
20
;
private
static
MERGE_CURSOR_CHANGES_THRESHOLD
=
100
;
private
stack
:
IStackEntry
[];
private
index
:
number
;
...
...
@@ -406,12 +408,12 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic
}
protected
handleEditorSelectionChangeEvent
(
editor
?:
IBaseEditor
):
void
{
this
.
handleEditorEventInStack
(
editor
,
true
);
this
.
handleEditorEventInStack
(
editor
);
}
protected
handleActiveEditorChange
(
editor
?:
IBaseEditor
):
void
{
this
.
handleEditorEventInHistory
(
editor
);
this
.
handleEditorEventInStack
(
editor
,
false
);
this
.
handleEditorEventInStack
(
editor
);
}
private
handleEditorEventInHistory
(
editor
?:
IBaseEditor
):
void
{
...
...
@@ -460,13 +462,13 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic
this
.
history
=
this
.
history
.
filter
(
e
=>
!
this
.
matches
(
arg1
,
e
));
}
private
handleEditorEventInStack
(
editor
:
IBaseEditor
,
storeSelection
:
boolean
):
void
{
private
handleEditorEventInStack
(
editor
:
IBaseEditor
):
void
{
if
(
this
.
blockStackChanges
)
{
return
;
// while we open an editor due to a navigation, we do not want to update our stack
}
if
(
editor
instanceof
BaseTextEditor
&&
editor
.
input
)
{
this
.
handleTextEditorEvent
(
<
BaseTextEditor
>
editor
,
storeSelection
);
this
.
handleTextEditorEvent
(
<
BaseTextEditor
>
editor
);
return
;
}
...
...
@@ -478,14 +480,15 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic
}
}
private
handleTextEditorEvent
(
editor
:
BaseTextEditor
,
storeSelection
:
boolean
):
void
{
private
handleTextEditorEvent
(
editor
:
BaseTextEditor
):
void
{
const
stateCandidate
=
new
EditorState
(
editor
.
input
,
editor
.
getSelection
());
if
(
!
this
.
currentFileEditorState
||
this
.
currentFileEditorState
.
justifiesNewPushState
(
stateCandidate
))
{
this
.
currentFileEditorState
=
stateCandidate
;
let
options
:
ITextEditorOptions
;
if
(
storeSelection
)
{
const
selection
=
editor
.
getSelection
();
const
selection
=
editor
.
getSelection
();
if
(
selection
)
{
options
=
{
selection
:
{
startLineNumber
:
selection
.
startLineNumber
,
startColumn
:
selection
.
startColumn
}
};
...
...
@@ -514,17 +517,21 @@ export class HistoryService extends BaseHistoryService implements IHistoryServic
// Overwrite an entry in the stack if we have a matching input that comes
// with editor options to indicate that this entry is more specific. Also
// prevent entries that have the exact same options.
// prevent entries that have the exact same options. Finally, Overwrite
// entries if we detect that the change came in very fast which indicates
// that it was not coming in from a user change but rather rapid programmatic
// changes. We just take the last of the changes to not cause too many
// entries on the stack.
let
replace
=
false
;
if
(
this
.
stack
[
this
.
index
])
{
const
currentEntry
=
this
.
stack
[
this
.
index
];
if
(
this
.
matches
(
input
,
currentEntry
.
input
)
&&
this
.
sameOptions
(
currentEntry
.
options
,
options
))
{
if
(
this
.
matches
(
input
,
currentEntry
.
input
)
&&
(
this
.
sameOptions
(
currentEntry
.
options
,
options
)
||
Date
.
now
()
-
currentEntry
.
timestamp
<
HistoryService
.
MERGE_CURSOR_CHANGES_THRESHOLD
))
{
replace
=
true
;
}
}
const
stackInput
=
this
.
preferResourceInput
(
input
);
const
entry
=
{
input
:
stackInput
,
options
};
const
entry
=
{
input
:
stackInput
,
options
,
timestamp
:
Date
.
now
()
};
// If we are not at the end of history, we remove anything after
if
(
this
.
stack
.
length
>
this
.
index
+
1
)
{
...
...
src/vs/workbench/services/textfile/common/textFileEditorModel.ts
浏览文件 @
fae8b9b7
...
...
@@ -108,9 +108,10 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
this
.
toDispose
.
push
(
this
.
textFileService
.
onFilesAssociationChange
(
e
=>
this
.
onFilesAssociationChange
()));
this
.
toDispose
.
push
(
this
.
onDidStateChange
(
e
=>
{
if
(
e
===
StateChange
.
REVERTED
)
{
// Refire reverted events as content change events, cancelling any content change
// promises that are in flight.
// Cancel any content change event promises as they are no longer valid.
this
.
contentChangeEventScheduler
.
cancel
();
// Refire state change reverted events as content change events
this
.
_onDidContentChange
.
fire
(
StateChange
.
REVERTED
);
}
}));
...
...
@@ -549,6 +550,9 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
// Updated resolved stat with updated stat, and keep old for event
this
.
updateVersionOnDiskStat
(
stat
);
// Cancel any content change event promises as they are no longer valid
this
.
contentChangeEventScheduler
.
cancel
();
// Emit File Saved Event
this
.
_onDidStateChange
.
fire
(
StateChange
.
SAVED
);
},
(
error
)
=>
{
...
...
@@ -770,6 +774,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
this
.
createTextEditorModelPromise
=
null
;
this
.
cancelAutoSavePromises
();
this
.
contentChangeEventScheduler
.
cancel
();
super
.
dispose
();
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录