Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
228978ab
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,发现更多精彩内容 >>
提交
228978ab
编写于
2月 07, 2019
作者:
M
Matt Bierner
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Strict null work in mainThreadSave
上级
1cd1f811
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
40 addition
and
40 deletion
+40
-40
src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts
...rkbench/api/electron-browser/mainThreadSaveParticipant.ts
+8
-8
src/vs/workbench/common/editor.ts
src/vs/workbench/common/editor.ts
+1
-1
src/vs/workbench/services/textfile/common/textFileEditorModel.ts
...workbench/services/textfile/common/textFileEditorModel.ts
+12
-12
src/vs/workbench/services/textfile/common/textfiles.ts
src/vs/workbench/services/textfile/common/textfiles.ts
+2
-2
src/vs/workbench/test/electron-browser/api/mainThreadSaveParticipant.test.ts
...st/electron-browser/api/mainThreadSaveParticipant.test.ts
+17
-17
未找到文件。
src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts
浏览文件 @
228978ab
...
...
@@ -7,7 +7,7 @@ import { isNonEmptyArray } from 'vs/base/common/arrays';
import
{
IdleValue
,
sequence
}
from
'
vs/base/common/async
'
;
import
{
CancellationTokenSource
,
CancellationToken
}
from
'
vs/base/common/cancellation
'
;
import
*
as
strings
from
'
vs/base/common/strings
'
;
import
{
ICodeEditor
}
from
'
vs/editor/browser/editorBrowser
'
;
import
{
ICodeEditor
,
IActiveCodeEditor
}
from
'
vs/editor/browser/editorBrowser
'
;
import
{
IBulkEditService
}
from
'
vs/editor/browser/services/bulkEditService
'
;
import
{
ICodeEditorService
}
from
'
vs/editor/browser/services/codeEditorService
'
;
import
{
trimTrailingWhitespace
}
from
'
vs/editor/common/commands/trimTrailingWhitespaceCommand
'
;
...
...
@@ -60,7 +60,7 @@ class TrimWhitespaceParticipant implements ISaveParticipantParticipant {
let
prevSelection
:
Selection
[]
=
[];
let
cursors
:
Position
[]
=
[];
le
t
editor
=
findEditor
(
model
,
this
.
codeEditorService
);
cons
t
editor
=
findEditor
(
model
,
this
.
codeEditorService
);
if
(
editor
)
{
// Find `prevSelection` in any case do ensure a good undo stack when pushing the edit
// Collect active cursors in `cursors` only if `isAutoSaved` to avoid having the cursors jump
...
...
@@ -85,12 +85,12 @@ class TrimWhitespaceParticipant implements ISaveParticipantParticipant {
}
}
function
findEditor
(
model
:
ITextModel
,
codeEditorService
:
ICodeEditorService
):
I
CodeEditor
{
let
candidate
:
ICodeEditor
|
null
=
null
;
function
findEditor
(
model
:
ITextModel
,
codeEditorService
:
ICodeEditorService
):
I
ActiveCodeEditor
|
null
{
let
candidate
:
I
Active
CodeEditor
|
null
=
null
;
if
(
model
.
isAttachedToEditor
())
{
for
(
const
editor
of
codeEditorService
.
listCodeEditors
())
{
if
(
editor
.
getModel
()
===
model
)
{
if
(
editor
.
hasModel
()
&&
editor
.
getModel
()
===
model
)
{
if
(
editor
.
hasTextFocus
())
{
return
editor
;
// favour focused editor if there are multiple
}
...
...
@@ -233,7 +233,7 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant {
const
timeout
=
this
.
_configurationService
.
getValue
<
number
>
(
'
editor.formatOnSaveTimeout
'
,
{
overrideIdentifier
:
model
.
getLanguageIdentifier
().
language
,
resource
:
editorModel
.
getResource
()
});
return
new
Promise
<
ISingleEditOperation
[]
>
((
resolve
,
reject
)
=>
{
return
new
Promise
<
ISingleEditOperation
[]
|
null
|
undefined
>
((
resolve
,
reject
)
=>
{
let
source
=
new
CancellationTokenSource
();
let
request
=
getDocumentFormattingEdits
(
model
,
{
tabSize
,
insertSpaces
},
source
.
token
);
...
...
@@ -277,7 +277,7 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant {
return
[
new
Selection
(
range
.
startLineNumber
,
range
.
startColumn
,
range
.
endLineNumber
,
range
.
endColumn
)];
}
}
return
undefined
;
return
null
;
});
}
...
...
@@ -425,7 +425,7 @@ export class SaveParticipant implements ISaveParticipant {
}
dispose
():
void
{
TextFileEditorModel
.
setSaveParticipant
(
undefined
);
TextFileEditorModel
.
setSaveParticipant
(
null
);
this
.
_saveParticipants
.
dispose
();
}
...
...
src/vs/workbench/common/editor.ts
浏览文件 @
228978ab
...
...
@@ -638,7 +638,7 @@ export class EditorModel extends Disposable implements IEditorModel {
/**
* Causes this model to load returning a promise when loading is completed.
*/
load
():
Promise
<
EditorModel
>
{
load
():
Promise
<
I
EditorModel
>
{
return
Promise
.
resolve
(
this
);
}
...
...
src/vs/workbench/services/textfile/common/textFileEditorModel.ts
浏览文件 @
228978ab
...
...
@@ -45,8 +45,8 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
private
static
saveErrorHandler
:
ISaveErrorHandler
;
static
setSaveErrorHandler
(
handler
:
ISaveErrorHandler
):
void
{
TextFileEditorModel
.
saveErrorHandler
=
handler
;
}
private
static
saveParticipant
:
ISaveParticipant
;
static
setSaveParticipant
(
handler
:
ISaveParticipant
):
void
{
TextFileEditorModel
.
saveParticipant
=
handler
;
}
private
static
saveParticipant
:
ISaveParticipant
|
null
;
static
setSaveParticipant
(
handler
:
ISaveParticipant
|
null
):
void
{
TextFileEditorModel
.
saveParticipant
=
handler
;
}
private
readonly
_onDidContentChange
:
Emitter
<
StateChange
>
=
this
.
_register
(
new
Emitter
<
StateChange
>
());
get
onDidContentChange
():
Event
<
StateChange
>
{
return
this
.
_onDidContentChange
.
event
;
}
...
...
@@ -62,9 +62,9 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
private
bufferSavedVersionId
:
number
;
private
lastResolvedDiskStat
:
IFileStat
;
private
blockModelContentChange
:
boolean
;
private
autoSaveAfterMillies
:
number
;
private
autoSaveAfterMillies
?
:
number
;
private
autoSaveAfterMilliesEnabled
:
boolean
;
private
autoSaveDisposable
:
IDisposable
;
private
autoSaveDisposable
?
:
IDisposable
;
private
contentChangeEventScheduler
:
RunOnceScheduler
;
private
orphanedChangeEventScheduler
:
RunOnceScheduler
;
private
saveSequentializer
:
SaveSequentializer
;
...
...
@@ -129,7 +129,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
private
onFileChanges
(
e
:
FileChangesEvent
):
void
{
let
fileEventImpactsModel
=
false
;
let
newInOrphanModeGuess
:
boolean
;
let
newInOrphanModeGuess
:
boolean
|
undefined
;
// If we are currently orphaned, we check if the model file was added back
if
(
this
.
inOrphanMode
)
{
...
...
@@ -235,7 +235,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
});
}
load
(
options
?:
ILoadOptions
):
Promise
<
TextFileEditorModel
>
{
load
(
options
?:
ILoadOptions
):
Promise
<
I
TextFileEditorModel
>
{
this
.
logService
.
trace
(
'
load() - enter
'
,
this
.
resource
);
// It is very important to not reload the model when the model is dirty.
...
...
@@ -289,7 +289,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
const
allowBinary
=
this
.
isResolved
()
/* always allow if we resolved previously */
||
(
options
&&
options
.
allowBinary
);
// Decide on etag
let
etag
:
string
;
let
etag
:
string
|
undefined
;
if
(
forceReadFromDisk
)
{
etag
=
undefined
;
// reset ETag if we enforce to read from disk
}
else
if
(
this
.
lastResolvedDiskStat
)
{
...
...
@@ -491,7 +491,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
return
this
.
backupFileService
.
resolveBackupContent
(
backup
).
then
(
backupContent
=>
backupContent
,
error
=>
null
/* ignore errors */
);
}
protected
getOrCreateMode
(
modeService
:
IModeService
,
preferredModeIds
:
string
,
firstLineText
?:
string
):
ILanguageSelection
{
protected
getOrCreateMode
(
modeService
:
IModeService
,
preferredModeIds
:
string
|
undefined
,
firstLineText
?:
string
):
ILanguageSelection
{
return
modeService
.
createByFilepathOrFirstLine
(
this
.
resource
.
fsPath
,
firstLineText
);
}
...
...
@@ -914,7 +914,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
return
this
.
lastSaveAttemptTime
;
}
getETag
():
string
{
getETag
():
string
|
null
{
return
this
.
lastResolvedDiskStat
?
this
.
lastResolvedDiskStat
.
etag
:
null
;
}
...
...
@@ -1046,8 +1046,8 @@ interface ISaveOperation {
}
export
class
SaveSequentializer
{
private
_pendingSave
:
IPendingSave
;
private
_nextSave
:
ISaveOperation
;
private
_pendingSave
?
:
IPendingSave
;
private
_nextSave
?
:
ISaveOperation
;
hasPendingSave
(
versionId
?:
number
):
boolean
{
if
(
!
this
.
_pendingSave
)
{
...
...
@@ -1061,7 +1061,7 @@ export class SaveSequentializer {
return
!!
this
.
_pendingSave
;
}
get
pendingSave
():
Promise
<
void
>
{
get
pendingSave
():
Promise
<
void
>
|
undefined
{
return
this
.
_pendingSave
?
this
.
_pendingSave
.
promise
:
undefined
;
}
...
...
src/vs/workbench/services/textfile/common/textfiles.ts
浏览文件 @
228978ab
...
...
@@ -236,7 +236,7 @@ export interface ITextFileEditorModel extends ITextEditorModel, IEncodingSupport
hasState
(
state
:
ModelState
):
boolean
;
getETag
():
string
;
getETag
():
string
|
null
;
updatePreferredEncoding
(
encoding
:
string
):
void
;
...
...
@@ -246,7 +246,7 @@ export interface ITextFileEditorModel extends ITextEditorModel, IEncodingSupport
revert
(
soft
?:
boolean
):
Promise
<
void
>
;
createSnapshot
():
ITextSnapshot
;
createSnapshot
():
ITextSnapshot
|
null
;
isDirty
():
boolean
;
...
...
src/vs/workbench/test/electron-browser/api/mainThreadSaveParticipant.test.ts
浏览文件 @
228978ab
...
...
@@ -43,31 +43,31 @@ suite('MainThreadSaveParticipant', function () {
await
model
.
load
();
const
configService
=
new
TestConfigurationService
();
configService
.
setUserConfiguration
(
'
files
'
,
{
'
insertFinalNewline
'
:
true
});
const
participant
=
new
FinalNewLineParticipant
(
configService
,
undefined
);
const
participant
=
new
FinalNewLineParticipant
(
configService
,
undefined
!
);
// No new line for empty lines
let
lineContent
=
''
;
model
.
textEditorModel
.
setValue
(
lineContent
);
await
participant
.
participate
(
model
,
{
reason
:
SaveReason
.
EXPLICIT
});
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()),
lineContent
);
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()
!
),
lineContent
);
// No new line if last line already empty
lineContent
=
`Hello New Line
${
model
.
textEditorModel
.
getEOL
()}
`
;
model
.
textEditorModel
.
setValue
(
lineContent
);
await
participant
.
participate
(
model
,
{
reason
:
SaveReason
.
EXPLICIT
});
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()),
lineContent
);
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()
!
),
lineContent
);
// New empty line added (single line)
lineContent
=
'
Hello New Line
'
;
model
.
textEditorModel
.
setValue
(
lineContent
);
await
participant
.
participate
(
model
,
{
reason
:
SaveReason
.
EXPLICIT
});
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()),
`
${
lineContent
}${
model
.
textEditorModel
.
getEOL
()}
`
);
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()
!
),
`
${
lineContent
}${
model
.
textEditorModel
.
getEOL
()}
`
);
// New empty line added (multi line)
lineContent
=
`Hello New Line
${
model
.
textEditorModel
.
getEOL
()}
Hello New Line
${
model
.
textEditorModel
.
getEOL
()}
Hello New Line`
;
model
.
textEditorModel
.
setValue
(
lineContent
);
await
participant
.
participate
(
model
,
{
reason
:
SaveReason
.
EXPLICIT
});
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()),
`
${
lineContent
}${
model
.
textEditorModel
.
getEOL
()}
`
);
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()
!
),
`
${
lineContent
}${
model
.
textEditorModel
.
getEOL
()}
`
);
});
test
(
'
trim final new lines
'
,
async
function
()
{
...
...
@@ -76,7 +76,7 @@ suite('MainThreadSaveParticipant', function () {
await
model
.
load
();
const
configService
=
new
TestConfigurationService
();
configService
.
setUserConfiguration
(
'
files
'
,
{
'
trimFinalNewlines
'
:
true
});
const
participant
=
new
TrimFinalNewLinesParticipant
(
configService
,
undefined
);
const
participant
=
new
TrimFinalNewLinesParticipant
(
configService
,
undefined
!
);
const
textContent
=
'
Trim New Line
'
;
const
eol
=
`
${
model
.
textEditorModel
.
getEOL
()}
`
;
...
...
@@ -84,25 +84,25 @@ suite('MainThreadSaveParticipant', function () {
let
lineContent
=
`
${
textContent
}
`
;
model
.
textEditorModel
.
setValue
(
lineContent
);
await
participant
.
participate
(
model
,
{
reason
:
SaveReason
.
EXPLICIT
});
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()),
lineContent
);
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()
!
),
lineContent
);
// No new line removal if last line is single new line
lineContent
=
`
${
textContent
}${
eol
}
`
;
model
.
textEditorModel
.
setValue
(
lineContent
);
await
participant
.
participate
(
model
,
{
reason
:
SaveReason
.
EXPLICIT
});
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()),
lineContent
);
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()
!
),
lineContent
);
// Remove new line (single line with two new lines)
lineContent
=
`
${
textContent
}${
eol
}${
eol
}
`
;
model
.
textEditorModel
.
setValue
(
lineContent
);
await
participant
.
participate
(
model
,
{
reason
:
SaveReason
.
EXPLICIT
});
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()),
`
${
textContent
}${
eol
}
`
);
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()
!
),
`
${
textContent
}${
eol
}
`
);
// Remove new lines (multiple lines with multiple new lines)
lineContent
=
`
${
textContent
}${
eol
}${
textContent
}${
eol
}${
eol
}${
eol
}
`
;
model
.
textEditorModel
.
setValue
(
lineContent
);
await
participant
.
participate
(
model
,
{
reason
:
SaveReason
.
EXPLICIT
});
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()),
`
${
textContent
}${
eol
}${
textContent
}${
eol
}
`
);
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()
!
),
`
${
textContent
}${
eol
}${
textContent
}${
eol
}
`
);
});
test
(
'
trim final new lines bug#39750
'
,
async
function
()
{
...
...
@@ -111,7 +111,7 @@ suite('MainThreadSaveParticipant', function () {
await
model
.
load
();
const
configService
=
new
TestConfigurationService
();
configService
.
setUserConfiguration
(
'
files
'
,
{
'
trimFinalNewlines
'
:
true
});
const
participant
=
new
TrimFinalNewLinesParticipant
(
configService
,
undefined
);
const
participant
=
new
TrimFinalNewLinesParticipant
(
configService
,
undefined
!
);
const
textContent
=
'
Trim New Line
'
;
// single line
...
...
@@ -124,12 +124,12 @@ suite('MainThreadSaveParticipant', function () {
// undo
model
.
textEditorModel
.
undo
();
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()),
`
${
textContent
}
`
);
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()
!
),
`
${
textContent
}
`
);
// trim final new lines should not mess the undo stack
await
participant
.
participate
(
model
,
{
reason
:
SaveReason
.
EXPLICIT
});
model
.
textEditorModel
.
redo
();
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()),
`
${
textContent
}
.`
);
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()
!
),
`
${
textContent
}
.`
);
});
test
(
'
trim final new lines bug#46075
'
,
async
function
()
{
...
...
@@ -138,7 +138,7 @@ suite('MainThreadSaveParticipant', function () {
await
model
.
load
();
const
configService
=
new
TestConfigurationService
();
configService
.
setUserConfiguration
(
'
files
'
,
{
'
trimFinalNewlines
'
:
true
});
const
participant
=
new
TrimFinalNewLinesParticipant
(
configService
,
undefined
);
const
participant
=
new
TrimFinalNewLinesParticipant
(
configService
,
undefined
!
);
const
textContent
=
'
Test
'
;
const
eol
=
`
${
model
.
textEditorModel
.
getEOL
()}
`
;
let
content
=
`
${
textContent
}${
eol
}${
eol
}
`
;
...
...
@@ -150,12 +150,12 @@ suite('MainThreadSaveParticipant', function () {
}
// confirm trimming
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()),
`
${
textContent
}${
eol
}
`
);
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()
!
),
`
${
textContent
}${
eol
}
`
);
// undo should go back to previous content immediately
model
.
textEditorModel
.
undo
();
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()),
`
${
textContent
}${
eol
}${
eol
}
`
);
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()
!
),
`
${
textContent
}${
eol
}${
eol
}
`
);
model
.
textEditorModel
.
redo
();
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()),
`
${
textContent
}${
eol
}
`
);
assert
.
equal
(
snapshotToString
(
model
.
createSnapshot
()
!
),
`
${
textContent
}${
eol
}
`
);
});
});
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录