Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
31536dd6
V
vscode
项目概览
掘金者说
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
31536dd6
编写于
4月 23, 2021
作者:
B
Benjamin Pasero
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
editors - make findEditors more powerful
上级
c32f1cc4
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
184 addition
and
42 deletion
+184
-42
src/vs/workbench/contrib/files/browser/editors/textFileSaveErrorHandler.ts
...contrib/files/browser/editors/textFileSaveErrorHandler.ts
+13
-18
src/vs/workbench/services/editor/browser/editorService.ts
src/vs/workbench/services/editor/browser/editorService.ts
+75
-8
src/vs/workbench/services/editor/common/editorService.ts
src/vs/workbench/services/editor/common/editorService.ts
+6
-2
src/vs/workbench/services/editor/test/browser/editorService.test.ts
...kbench/services/editor/test/browser/editorService.test.ts
+89
-13
src/vs/workbench/test/browser/workbenchTestServices.ts
src/vs/workbench/test/browser/workbenchTestServices.ts
+1
-1
未找到文件。
src/vs/workbench/contrib/files/browser/editors/textFileSaveErrorHandler.ts
浏览文件 @
31536dd6
...
...
@@ -30,7 +30,6 @@ import { isWindows } from 'vs/base/common/platform';
import
{
Schemas
}
from
'
vs/base/common/network
'
;
import
{
IPreferencesService
}
from
'
vs/workbench/services/preferences/common/preferences
'
;
import
{
IEditorIdentifier
,
SaveReason
}
from
'
vs/workbench/common/editor
'
;
import
{
GroupsOrder
,
IEditorGroupsService
}
from
'
vs/workbench/services/editor/common/editorGroupsService
'
;
import
{
hash
}
from
'
vs/base/common/hash
'
;
export
const
CONFLICT_RESOLUTION_CONTEXT
=
'
saveConflictResolutionContext
'
;
...
...
@@ -321,8 +320,7 @@ class SaveModelAsAction extends Action {
constructor
(
private
model
:
ITextFileEditorModel
,
@
IEditorService
private
editorService
:
IEditorService
,
@
IEditorGroupsService
private
editorGroupService
:
IEditorGroupsService
@
IEditorService
private
editorService
:
IEditorService
)
{
super
(
'
workbench.files.action.saveModelAs
'
,
SAVE_FILE_AS_LABEL
);
}
...
...
@@ -338,25 +336,22 @@ class SaveModelAsAction extends Action {
private
findEditor
():
IEditorIdentifier
|
undefined
{
let
preferredMatchingEditor
:
IEditorIdentifier
|
undefined
;
let
otherMatchingEditors
:
IEditorIdentifier
[]
=
[];
FindEditorLoop
:
for
(
const
group
of
this
.
editorGroupService
.
getGroups
(
GroupsOrder
.
MOST_RECENTLY_ACTIVE
))
{
const
editors
=
this
.
editorService
.
findEditors
(
this
.
model
.
resource
,
group
);
for
(
const
editor
of
editors
)
{
if
(
editor
instanceof
FileEditorInput
)
{
// We prefer a `FileEditorInput` for "Save As", but it is possible
// that a custom editor is leveraging the text file model and as
// such we need to fallback to any other editor having the resource
// opened for running the save.
preferredMatchingEditor
=
{
editor
,
groupId
:
group
.
id
};
break
FindEditorLoop
;
}
otherMatchingEditors
.
push
({
editor
,
groupId
:
group
.
id
});
const
editors
=
this
.
editorService
.
findEditors
(
this
.
model
.
resource
);
for
(
const
identifier
of
editors
)
{
if
(
identifier
.
editor
instanceof
FileEditorInput
)
{
// We prefer a `FileEditorInput` for "Save As", but it is possible
// that a custom editor is leveraging the text file model and as
// such we need to fallback to any other editor having the resource
// opened for running the save.
preferredMatchingEditor
=
identifier
;
break
;
}
else
if
(
!
preferredMatchingEditor
)
{
preferredMatchingEditor
=
identifier
;
}
}
return
preferredMatchingEditor
||
otherMatchingEditors
[
0
]
;
return
preferredMatchingEditor
;
}
}
...
...
src/vs/workbench/services/editor/browser/editorService.ts
浏览文件 @
31536dd6
...
...
@@ -24,7 +24,7 @@ import { coalesce, distinct, firstOrDefault, insert } from 'vs/base/common/array
import
{
isCodeEditor
,
isDiffEditor
,
ICodeEditor
,
IDiffEditor
,
isCompositeEditor
}
from
'
vs/editor/browser/editorBrowser
'
;
import
{
IEditorGroupView
,
EditorServiceImpl
}
from
'
vs/workbench/browser/parts/editor/editor
'
;
import
{
registerSingleton
}
from
'
vs/platform/instantiation/common/extensions
'
;
import
{
withNullAsUndefined
}
from
'
vs/base/common/types
'
;
import
{
isUndefined
,
withNullAsUndefined
}
from
'
vs/base/common/types
'
;
import
{
EditorsObserver
}
from
'
vs/workbench/browser/parts/editor/editorsObserver
'
;
import
{
IEditorViewState
}
from
'
vs/editor/common/editorCommon
'
;
import
{
IUntitledTextEditorModel
}
from
'
vs/workbench/services/untitled/common/untitledTextEditorModel
'
;
...
...
@@ -856,17 +856,80 @@ export class EditorService extends Disposable implements EditorServiceImpl {
//#region findEditors()
findEditors
(
resource
:
URI
,
group
:
IEditorGroup
|
GroupIdentifier
):
ReadonlyArray
<
IEditorInput
>
{
findEditors
(
resource
:
URI
):
ReadonlyArray
<
IEditorIdentifier
>
;
findEditors
(
editor
:
IResourceEditorInputIdentifier
):
ReadonlyArray
<
IEditorIdentifier
>
;
findEditors
(
resource
:
URI
,
group
:
IEditorGroup
|
GroupIdentifier
):
ReadonlyArray
<
IEditorInput
>
;
findEditors
(
editor
:
IResourceEditorInputIdentifier
,
group
:
IEditorGroup
|
GroupIdentifier
):
IEditorInput
|
undefined
;
findEditors
(
arg1
:
URI
|
IResourceEditorInputIdentifier
,
arg2
?:
IEditorGroup
|
GroupIdentifier
):
ReadonlyArray
<
IEditorIdentifier
>
|
ReadonlyArray
<
IEditorInput
>
|
IEditorInput
|
undefined
;
findEditors
(
arg1
:
URI
|
IResourceEditorInputIdentifier
,
arg2
?:
IEditorGroup
|
GroupIdentifier
):
ReadonlyArray
<
IEditorIdentifier
>
|
ReadonlyArray
<
IEditorInput
>
|
IEditorInput
|
undefined
{
const
resource
=
URI
.
isUri
(
arg1
)
?
arg1
:
arg1
.
resource
;
const
typeId
=
URI
.
isUri
(
arg1
)
?
undefined
:
arg1
.
typeId
;
// Do a quick check for the resource via the editor observer
// which is a very efficient way to find an editor by resource
if
(
!
this
.
editorsObserver
.
hasEditors
(
resource
))
{
return
[];
// this is a very fast efficient check via editor observer
if
(
URI
.
isUri
(
arg1
)
||
isUndefined
(
arg2
))
{
return
[];
}
return
undefined
;
}
const
targetGroup
=
typeof
group
===
'
number
'
?
this
.
editorGroupService
.
getGroup
(
group
)
:
group
;
if
(
!
targetGroup
)
{
return
[];
// Search only in specific group
if
(
!
isUndefined
(
arg2
))
{
const
targetGroup
=
typeof
arg2
===
'
number
'
?
this
.
editorGroupService
.
getGroup
(
arg2
)
:
arg2
;
// Resource provided: result is an array
if
(
URI
.
isUri
(
arg1
))
{
if
(
!
targetGroup
)
{
return
[];
}
return
targetGroup
.
findEditors
(
resource
);
}
// Editor identifier provided, result is single
else
{
if
(
!
targetGroup
)
{
return
undefined
;
}
const
editors
=
targetGroup
.
findEditors
(
resource
);
for
(
const
editor
of
editors
)
{
if
(
editor
.
typeId
===
typeId
)
{
return
editor
;
}
}
return
undefined
;
}
}
return
targetGroup
.
findEditors
(
resource
);
// Search across all groups in MRU order
else
{
const
result
:
IEditorIdentifier
[]
=
[];
for
(
const
group
of
this
.
editorGroupService
.
getGroups
(
GroupsOrder
.
MOST_RECENTLY_ACTIVE
))
{
const
editors
:
IEditorInput
[]
=
[];
// Resource provided: result is an array
if
(
URI
.
isUri
(
arg1
))
{
editors
.
push
(...
this
.
findEditors
(
arg1
,
group
));
}
// Editor identifier provided, result is single
else
{
const
editor
=
this
.
findEditors
(
arg1
,
group
);
if
(
editor
)
{
editors
.
push
(
editor
);
}
}
result
.
push
(...
editors
.
map
(
editor
=>
({
editor
,
groupId
:
group
.
id
})));
}
return
result
;
}
}
//#endregion
...
...
@@ -1321,7 +1384,11 @@ export class DelegatingEditorService implements IEditorService {
isOpened
(
editor
:
IResourceEditorInputIdentifier
):
boolean
{
return
this
.
editorService
.
isOpened
(
editor
);
}
findEditors
(
resource
:
URI
,
group
:
IEditorGroup
|
GroupIdentifier
):
ReadonlyArray
<
IEditorInput
>
{
return
this
.
editorService
.
findEditors
(
resource
,
group
);
}
findEditors
(
resource
:
URI
):
ReadonlyArray
<
IEditorIdentifier
>
;
findEditors
(
resource
:
IResourceEditorInputIdentifier
):
ReadonlyArray
<
IEditorIdentifier
>
;
findEditors
(
resource
:
URI
,
group
:
IEditorGroup
|
GroupIdentifier
):
ReadonlyArray
<
IEditorInput
>
;
findEditors
(
resource
:
IResourceEditorInputIdentifier
,
group
:
IEditorGroup
|
GroupIdentifier
):
IEditorInput
|
undefined
;
findEditors
(
arg1
:
URI
|
IResourceEditorInputIdentifier
,
arg2
?:
IEditorGroup
|
GroupIdentifier
):
ReadonlyArray
<
IEditorIdentifier
>
|
ReadonlyArray
<
IEditorInput
>
|
IEditorInput
|
undefined
{
return
this
.
editorService
.
findEditors
(
arg1
,
arg2
);
}
overrideOpenEditor
(
handler
:
IOpenEditorOverrideHandler
):
IDisposable
{
return
this
.
editorService
.
overrideOpenEditor
(
handler
);
}
getEditorOverrides
(
resource
:
URI
,
options
:
IEditorOptions
|
undefined
,
group
:
IEditorGroup
|
undefined
)
{
return
this
.
editorService
.
getEditorOverrides
(
resource
,
options
,
group
);
}
...
...
src/vs/workbench/services/editor/common/editorService.ts
浏览文件 @
31536dd6
...
...
@@ -221,13 +221,17 @@ export interface IEditorService {
/**
* This method will return an entry for each editor that reports
* a `resource` that matches the provided one in the group.
* a `resource` that matches the provided one in the group or
* across all groups.
*
* It is possible that multiple editors are returned in case the
* same resource is opened in different editors. To find the specific
* editor,
either check on the `typeId` or do an `instanceof` check
.
* editor,
use the `IResourceEditorInputIdentifier` as input
.
*/
findEditors
(
resource
:
URI
):
ReadonlyArray
<
IEditorIdentifier
>
;
findEditors
(
resource
:
IResourceEditorInputIdentifier
):
ReadonlyArray
<
IEditorIdentifier
>
;
findEditors
(
resource
:
URI
,
group
:
IEditorGroup
|
GroupIdentifier
):
ReadonlyArray
<
IEditorInput
>
;
findEditors
(
resource
:
IResourceEditorInputIdentifier
,
group
:
IEditorGroup
|
GroupIdentifier
):
IEditorInput
|
undefined
;
/**
* Get all available editor overrides for the editor input.
...
...
src/vs/workbench/services/editor/test/browser/editorService.test.ts
浏览文件 @
31536dd6
...
...
@@ -1026,7 +1026,7 @@ suite('EditorService', () => {
handler
.
dispose
();
});
test
(
'
findEditors
'
,
async
()
=>
{
test
(
'
findEditors
(in group)
'
,
async
()
=>
{
const
[
part
,
service
]
=
await
createEditorService
();
const
input
=
new
TestFileEditorInput
(
URI
.
parse
(
'
my://resource-openEditors
'
),
TEST_EDITOR_INPUT_ID
);
...
...
@@ -1038,35 +1038,111 @@ suite('EditorService', () => {
// Try using find editors for opened editors
{
const
found
=
service
.
findEditors
(
input
.
resource
,
part
.
activeGroup
);
assert
.
strictEqual
(
found
.
length
,
1
);
assert
.
strictEqual
(
found
[
0
],
input
);
const
found1
=
service
.
findEditors
(
input
.
resource
,
part
.
activeGroup
);
assert
.
strictEqual
(
found1
.
length
,
1
);
assert
.
strictEqual
(
found1
[
0
],
input
);
const
found2
=
service
.
findEditors
(
input
,
part
.
activeGroup
);
assert
.
strictEqual
(
found2
,
input
);
}
{
const
found
=
service
.
findEditors
(
otherInput
.
resource
,
part
.
activeGroup
);
assert
.
strictEqual
(
found
.
length
,
1
);
assert
.
strictEqual
(
found
[
0
],
otherInput
);
const
found1
=
service
.
findEditors
(
otherInput
.
resource
,
part
.
activeGroup
);
assert
.
strictEqual
(
found1
.
length
,
1
);
assert
.
strictEqual
(
found1
[
0
],
otherInput
);
const
found2
=
service
.
findEditors
(
otherInput
,
part
.
activeGroup
);
assert
.
strictEqual
(
found2
,
otherInput
);
}
// Make sure we don't find non-opened editors
{
const
found
=
service
.
findEditors
(
URI
.
parse
(
'
my://no-such-resource
'
),
part
.
activeGroup
);
assert
.
strictEqual
(
found
.
length
,
0
);
const
found1
=
service
.
findEditors
(
URI
.
parse
(
'
my://no-such-resource
'
),
part
.
activeGroup
);
assert
.
strictEqual
(
found1
.
length
,
0
);
const
found2
=
service
.
findEditors
({
resource
:
URI
.
parse
(
'
my://no-such-resource
'
),
typeId
:
''
},
part
.
activeGroup
);
assert
.
strictEqual
(
found2
,
undefined
);
}
// Make sure we don't find editors across groups
{
const
newEditor
=
await
service
.
openEditor
(
new
TestFileEditorInput
(
URI
.
parse
(
'
my://other-group-resource
'
),
TEST_EDITOR_INPUT_ID
),
{
pinned
:
true
,
preserveFocus
:
true
},
SIDE_GROUP
);
const
found
=
service
.
findEditors
(
input
.
resource
,
newEditor
!
.
group
!
.
id
);
assert
.
strictEqual
(
found
.
length
,
0
);
const
found1
=
service
.
findEditors
(
input
.
resource
,
newEditor
!
.
group
!
.
id
);
assert
.
strictEqual
(
found1
.
length
,
0
);
const
found2
=
service
.
findEditors
(
input
,
newEditor
!
.
group
!
.
id
);
assert
.
strictEqual
(
found2
,
undefined
);
}
// Check we don't find editors after closing them
await
part
.
activeGroup
.
closeAllEditors
();
{
const
found
=
service
.
findEditors
(
input
.
resource
,
part
.
activeGroup
);
assert
.
strictEqual
(
found
.
length
,
0
);
const
found1
=
service
.
findEditors
(
input
.
resource
,
part
.
activeGroup
);
assert
.
strictEqual
(
found1
.
length
,
0
);
const
found2
=
service
.
findEditors
(
input
,
part
.
activeGroup
);
assert
.
strictEqual
(
found2
,
undefined
);
}
});
test
(
'
findEditors (across groups)
'
,
async
()
=>
{
const
[
part
,
service
]
=
await
createEditorService
();
const
rootGroup
=
part
.
activeGroup
;
const
input
=
new
TestFileEditorInput
(
URI
.
parse
(
'
my://resource-openEditors
'
),
TEST_EDITOR_INPUT_ID
);
const
otherInput
=
new
TestFileEditorInput
(
URI
.
parse
(
'
my://resource2-openEditors
'
),
TEST_EDITOR_INPUT_ID
);
// Open editors
await
service
.
openEditors
([{
editor
:
input
},
{
editor
:
otherInput
}]);
const
sideEditor
=
await
service
.
openEditor
(
input
,
{
pinned
:
true
},
SIDE_GROUP
);
// Try using find editors for opened editors
{
const
found1
=
service
.
findEditors
(
input
.
resource
);
assert
.
strictEqual
(
found1
.
length
,
2
);
assert
.
strictEqual
(
found1
[
0
].
editor
,
input
);
assert
.
strictEqual
(
found1
[
0
].
groupId
,
sideEditor
?.
group
?.
id
);
assert
.
strictEqual
(
found1
[
1
].
editor
,
input
);
assert
.
strictEqual
(
found1
[
1
].
groupId
,
rootGroup
.
id
);
const
found2
=
service
.
findEditors
(
input
);
assert
.
strictEqual
(
found2
.
length
,
2
);
assert
.
strictEqual
(
found2
[
0
].
editor
,
input
);
assert
.
strictEqual
(
found2
[
0
].
groupId
,
sideEditor
?.
group
?.
id
);
assert
.
strictEqual
(
found2
[
1
].
editor
,
input
);
assert
.
strictEqual
(
found2
[
1
].
groupId
,
rootGroup
.
id
);
}
{
const
found1
=
service
.
findEditors
(
otherInput
.
resource
);
assert
.
strictEqual
(
found1
.
length
,
1
);
assert
.
strictEqual
(
found1
[
0
].
editor
,
otherInput
);
assert
.
strictEqual
(
found1
[
0
].
groupId
,
rootGroup
.
id
);
const
found2
=
service
.
findEditors
(
otherInput
);
assert
.
strictEqual
(
found2
.
length
,
1
);
assert
.
strictEqual
(
found2
[
0
].
editor
,
otherInput
);
assert
.
strictEqual
(
found2
[
0
].
groupId
,
rootGroup
.
id
);
}
// Make sure we don't find non-opened editors
{
const
found1
=
service
.
findEditors
(
URI
.
parse
(
'
my://no-such-resource
'
));
assert
.
strictEqual
(
found1
.
length
,
0
);
const
found2
=
service
.
findEditors
({
resource
:
URI
.
parse
(
'
my://no-such-resource
'
),
typeId
:
''
});
assert
.
strictEqual
(
found2
.
length
,
0
);
}
// Check we don't find editors after closing them
await
rootGroup
.
closeAllEditors
();
await
sideEditor
?.
group
?.
closeAllEditors
();
{
const
found1
=
service
.
findEditors
(
input
.
resource
);
assert
.
strictEqual
(
found1
.
length
,
0
);
const
found2
=
service
.
findEditors
(
input
);
assert
.
strictEqual
(
found2
.
length
,
0
);
}
});
});
src/vs/workbench/test/browser/workbenchTestServices.ts
浏览文件 @
31536dd6
...
...
@@ -781,7 +781,7 @@ export class TestEditorService implements EditorServiceImpl {
constructor
(
private
editorGroupService
?:
IEditorGroupsService
)
{
}
getEditors
()
{
return
[];
}
findEditors
()
{
return
[];
}
findEditors
()
{
return
[]
as
any
;
}
getEditorOverrides
(
resource
:
URI
,
options
:
IEditorOptions
|
undefined
,
group
:
IEditorGroup
|
undefined
):
[
IOpenEditorOverrideHandler
,
IOpenEditorOverrideEntry
][]
{
return
[];
}
overrideOpenEditor
(
_handler
:
IOpenEditorOverrideHandler
):
IDisposable
{
return
toDisposable
(()
=>
undefined
);
}
openEditor
(
editor
:
IEditorInput
,
options
?:
IEditorOptions
|
ITextEditorOptions
,
group
?:
IEditorGroup
|
GroupIdentifier
|
SIDE_GROUP_TYPE
|
ACTIVE_GROUP_TYPE
):
Promise
<
IEditorPane
|
undefined
>
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录