Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
7b9f3516
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
7b9f3516
编写于
9月 20, 2016
作者:
J
Johannes Rieken
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
make ISaveParticipant async
上级
23fef6b1
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
107 addition
and
48 deletion
+107
-48
src/vs/workbench/parts/files/common/editors/saveParticipant.ts
...s/workbench/parts/files/common/editors/saveParticipant.ts
+3
-1
src/vs/workbench/parts/files/common/editors/textFileEditorModel.ts
...rkbench/parts/files/common/editors/textFileEditorModel.ts
+61
-46
src/vs/workbench/parts/files/common/files.ts
src/vs/workbench/parts/files/common/files.ts
+1
-1
src/vs/workbench/parts/files/test/browser/fileEditorModel.test.ts
...orkbench/parts/files/test/browser/fileEditorModel.test.ts
+42
-0
未找到文件。
src/vs/workbench/parts/files/common/editors/saveParticipant.ts
浏览文件 @
7b9f3516
...
...
@@ -6,6 +6,7 @@
'
use strict
'
;
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
ICodeEditorService
}
from
'
vs/editor/common/services/codeEditorService
'
;
import
{
IWorkbenchContribution
}
from
'
vs/workbench/common/contributions
'
;
import
{
ISaveParticipant
,
ITextFileEditorModel
}
from
'
vs/workbench/parts/files/common/files
'
;
...
...
@@ -47,10 +48,11 @@ export class SaveParticipant implements ISaveParticipant, IWorkbenchContribution
this
.
trimTrailingWhitespace
=
configuration
&&
configuration
.
files
&&
configuration
.
files
.
trimTrailingWhitespace
;
}
public
participate
(
model
:
ITextFileEditorModel
,
env
:
{
isAutoSaved
:
boolean
}):
void
{
public
participate
(
model
:
ITextFileEditorModel
,
env
:
{
isAutoSaved
:
boolean
}):
TPromise
<
any
>
{
if
(
this
.
trimTrailingWhitespace
)
{
this
.
doTrimTrailingWhitespace
(
model
.
textEditorModel
,
env
.
isAutoSaved
);
}
return
TPromise
.
as
(
undefined
);
}
private
doTrimTrailingWhitespace
(
model
:
IModel
,
isAutoSaved
:
boolean
):
void
{
...
...
src/vs/workbench/parts/files/common/editors/textFileEditorModel.ts
浏览文件 @
7b9f3516
...
...
@@ -441,66 +441,81 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
// A save participant can still change the model now and since we are so close to saving
// we do not want to trigger another auto save or similar, so we block this
// In addition we update our version right after in case it changed because of a model change
let
saveParticipantPromise
=
TPromise
.
as
(
versionId
);
if
(
TextFileEditorModel
.
saveParticipant
)
{
this
.
blockModelContentChange
=
true
;
try
{
TextFileEditorModel
.
saveParticipant
.
participate
(
this
,
{
isAutoSaved
});
}
finally
{
saveParticipantPromise
=
TPromise
.
as
(
undefined
).
then
(()
=>
{
this
.
blockModelContentChange
=
true
;
return
TextFileEditorModel
.
saveParticipant
.
participate
(
this
,
{
isAutoSaved
});
}
).
then
(()
=>
{
this
.
blockModelContentChange
=
false
;
}
versionId
=
this
.
versionId
;
return
this
.
versionId
;
},
err
=>
{
this
.
blockModelContentChange
=
false
;
return
TPromise
.
wrapError
(
err
);
});
}
// Clear error flag since we are trying to save again
this
.
inErrorMode
=
false
;
this
.
mapPendingSaveToVersionId
[
versionId
]
=
saveParticipantPromise
.
then
(
newVersionId
=>
{
// Remember when this model was saved last
this
.
lastSaveAttemptTime
=
Date
.
now
();
// Save to Disk
diag
(
`doSave(
${
versionId
}
) - before updateContent()`
,
this
.
resource
,
new
Date
());
this
.
mapPendingSaveToVersionId
[
versionId
]
=
this
.
fileService
.
updateContent
(
this
.
versionOnDiskStat
.
resource
,
this
.
getValue
(),
{
overwriteReadonly
:
overwriteReadonly
,
overwriteEncoding
:
overwriteEncoding
,
mtime
:
this
.
versionOnDiskStat
.
mtime
,
encoding
:
this
.
getEncoding
(),
etag
:
this
.
versionOnDiskStat
.
etag
}).
then
((
stat
:
IFileStat
)
=>
{
diag
(
`doSave(
${
versionId
}
) - after updateContent()`
,
this
.
resource
,
new
Date
());
// Remove from pending saves
// remove save participant promise and update versionId with
// its new value (if pre-save changes happened)
delete
this
.
mapPendingSaveToVersionId
[
versionId
];
versionId
=
newVersionId
;
//
Telemetry
this
.
telemetryService
.
publicLog
(
'
filePUT
'
,
{
mimeType
:
stat
.
mime
,
ext
:
paths
.
extname
(
this
.
versionOnDiskStat
.
resource
.
fsPath
)
})
;
//
Clear error flag since we are trying to save again
this
.
inErrorMode
=
false
;
// Update dirty state unless model has changed meanwhile
if
(
versionId
===
this
.
versionId
)
{
diag
(
`doSave(
${
versionId
}
) - setting dirty to false because versionId did not change`
,
this
.
resource
,
new
Date
());
this
.
setDirty
(
false
);
}
else
{
diag
(
`doSave(
${
versionId
}
) - not setting dirty to false because versionId did change meanwhile`
,
this
.
resource
,
new
Date
());
}
// Remember when this model was saved last
this
.
lastSaveAttemptTime
=
Date
.
now
();
// Save to Disk
diag
(
`doSave(
${
versionId
}
) - before updateContent()`
,
this
.
resource
,
new
Date
());
this
.
mapPendingSaveToVersionId
[
versionId
]
=
this
.
fileService
.
updateContent
(
this
.
versionOnDiskStat
.
resource
,
this
.
getValue
(),
{
overwriteReadonly
:
overwriteReadonly
,
overwriteEncoding
:
overwriteEncoding
,
mtime
:
this
.
versionOnDiskStat
.
mtime
,
encoding
:
this
.
getEncoding
(),
etag
:
this
.
versionOnDiskStat
.
etag
}).
then
((
stat
:
IFileStat
)
=>
{
diag
(
`doSave(
${
versionId
}
) - after updateContent()`
,
this
.
resource
,
new
Date
());
// Remove from pending saves
delete
this
.
mapPendingSaveToVersionId
[
versionId
];
// Telemetry
this
.
telemetryService
.
publicLog
(
'
filePUT
'
,
{
mimeType
:
stat
.
mime
,
ext
:
paths
.
extname
(
this
.
versionOnDiskStat
.
resource
.
fsPath
)
});
// Update dirty state unless model has changed meanwhile
if
(
versionId
===
this
.
versionId
)
{
diag
(
`doSave(
${
versionId
}
) - setting dirty to false because versionId did not change`
,
this
.
resource
,
new
Date
());
this
.
setDirty
(
false
);
}
else
{
diag
(
`doSave(
${
versionId
}
) - not setting dirty to false because versionId did change meanwhile`
,
this
.
resource
,
new
Date
());
}
// Updated resolved stat with updated stat, and keep old for event
this
.
updateVersionOnDiskStat
(
stat
);
// Updated resolved stat with updated stat, and keep old for event
this
.
updateVersionOnDiskStat
(
stat
);
// Emit File Saved Event
this
.
_onDidStateChange
.
fire
(
StateChange
.
SAVED
);
},
(
error
)
=>
{
diag
(
`doSave(
${
versionId
}
) - exit - resulted in a save error:
${
error
.
toString
()}
`
,
this
.
resource
,
new
Date
());
// Emit File Saved Event
this
.
_onDidStateChange
.
fire
(
StateChange
.
SAVED
);
},
(
error
)
=>
{
diag
(
`doSave(
${
versionId
}
) - exit - resulted in a save error:
${
error
.
toString
()}
`
,
this
.
resource
,
new
Date
());
// Remove from pending saves
delete
this
.
mapPendingSaveToVersionId
[
versionId
];
// Remove from pending saves
delete
this
.
mapPendingSaveToVersionId
[
versionId
];
// Flag as error state
this
.
inErrorMode
=
true
;
// Flag as error state
this
.
inErrorMode
=
true
;
// Show to user
this
.
onSaveError
(
error
)
;
// Show to user
this
.
onSaveError
(
error
);
// Emit as event
this
.
_onDidStateChange
.
fire
(
StateChange
.
SAVE_ERROR
);
});
// Emit as event
this
.
_onDidStateChange
.
fire
(
StateChange
.
SAVE_ERROR
);
return
this
.
mapPendingSaveToVersionId
[
versionId
];
});
return
this
.
mapPendingSaveToVersionId
[
versionId
];
...
...
src/vs/workbench/parts/files/common/files.ts
浏览文件 @
7b9f3516
...
...
@@ -112,7 +112,7 @@ export interface ISaveParticipant {
/**
* Participate in a save of a model. Allows to change the model before it is being saved to disk.
*/
participate
(
model
:
ITextFileEditorModel
,
env
:
{
isAutoSaved
:
boolean
}):
void
;
participate
(
model
:
ITextFileEditorModel
,
env
:
{
isAutoSaved
:
boolean
}):
TPromise
<
any
>
;
}
/**
...
...
src/vs/workbench/parts/files/test/browser/fileEditorModel.test.ts
浏览文件 @
7b9f3516
...
...
@@ -294,6 +294,7 @@ suite('Files - TextFileEditorModel', () => {
model
.
textEditorModel
.
setValue
(
'
bar
'
);
assert
.
ok
(
model
.
isDirty
());
eventCounter
++
;
return
undefined
;
}
});
...
...
@@ -309,4 +310,45 @@ suite('Files - TextFileEditorModel', () => {
});
});
});
test
(
'
Save Participant, async participant
'
,
function
()
{
const
model
:
TextFileEditorModel
=
instantiationService
.
createInstance
(
TextFileEditorModel
,
toResource
(
'
/path/index_async.txt
'
),
'
utf8
'
);
TextFileEditorModel
.
setSaveParticipant
({
participate
:
(
model
)
=>
{
return
TPromise
.
timeout
(
10
);
}
});
return
model
.
load
().
then
(()
=>
{
model
.
textEditorModel
.
setValue
(
'
foo
'
);
const
now
=
Date
.
now
();
return
model
.
save
().
then
(()
=>
{
assert
.
ok
(
Date
.
now
()
-
now
>=
10
);
model
.
dispose
();
});
});
});
test
(
'
Save Participant, bad participant
'
,
function
()
{
const
model
:
TextFileEditorModel
=
instantiationService
.
createInstance
(
TextFileEditorModel
,
toResource
(
'
/path/index_async.txt
'
),
'
utf8
'
);
TextFileEditorModel
.
setSaveParticipant
({
participate
:
(
model
)
=>
{
return
TPromise
.
wrapError
(
'
boom
'
);
}
});
return
model
.
load
().
then
(()
=>
{
model
.
textEditorModel
.
setValue
(
'
foo
'
);
return
model
.
save
().
then
(()
=>
{
assert
.
ok
(
false
);
model
.
dispose
();
},
err
=>
{
assert
.
ok
(
err
);
});
});
});
});
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录