Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
掘金者说
vscode
提交
727774d6
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,发现更多精彩内容 >>
提交
727774d6
编写于
4月 30, 2018
作者:
J
Johannes Rieken
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
debt - make bulkEdit a service so that we can add create/delete/rename file to it
上级
8d139ed5
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
222 addition
and
123 deletion
+222
-123
build/lib/i18n.resources.json
build/lib/i18n.resources.json
+5
-1
src/vs/editor/browser/services/bulkEditService.ts
src/vs/editor/browser/services/bulkEditService.ts
+32
-0
src/vs/editor/contrib/codeAction/codeActionCommands.ts
src/vs/editor/contrib/codeAction/codeActionCommands.ts
+6
-11
src/vs/editor/contrib/rename/rename.ts
src/vs/editor/contrib/rename/rename.ts
+8
-12
src/vs/editor/standalone/browser/simpleServices.ts
src/vs/editor/standalone/browser/simpleServices.ts
+47
-1
src/vs/editor/standalone/browser/standaloneServices.ts
src/vs/editor/standalone/browser/standaloneServices.ts
+4
-1
src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts
...nch/api/electron-browser/mainThreadDocumentsAndEditors.ts
+5
-2
src/vs/workbench/api/electron-browser/mainThreadEditors.ts
src/vs/workbench/api/electron-browser/mainThreadEditors.ts
+14
-44
src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts
...rkbench/api/electron-browser/mainThreadSaveParticipant.ts
+3
-5
src/vs/workbench/parts/search/browser/replaceService.ts
src/vs/workbench/parts/search/browser/replaceService.ts
+5
-8
src/vs/workbench/services/bulkEdit/electron-browser/bulkEditService.ts
...nch/services/bulkEdit/electron-browser/bulkEditService.ts
+85
-35
src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts
...bench/test/electron-browser/api/mainThreadEditors.test.ts
+5
-3
src/vs/workbench/workbench.main.ts
src/vs/workbench/workbench.main.ts
+3
-0
未找到文件。
build/lib/i18n.resources.json
浏览文件 @
727774d6
...
...
@@ -150,6 +150,10 @@
"name"
:
"vs/workbench/services/actions"
,
"project"
:
"vscode-workbench"
},
{
"name"
:
"vs/workbench/services/bulkEdit"
,
"project"
:
"vscode-workbench"
},
{
"name"
:
"vs/workbench/services/configuration"
,
"project"
:
"vscode-workbench"
...
...
@@ -219,4 +223,4 @@
"project"
:
"vscode-preferences"
}
]
}
\ No newline at end of file
}
src/vs/editor/browser/services/bulkEditService.ts
0 → 100644
浏览文件 @
727774d6
/*---------------------------------------------------------------------------------------------
* 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
{
createDecorator
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
WorkspaceEdit
}
from
'
vs/editor/common/modes
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
ICodeEditor
}
from
'
../editorBrowser
'
;
import
{
Selection
}
from
'
vs/editor/common/core/selection
'
;
import
{
IProgressRunner
}
from
'
vs/platform/progress/common/progress
'
;
export
const
IBulkEditService
=
createDecorator
<
IBulkEditService
>
(
'
IWorkspaceEditService
'
);
export
interface
IBulkEditOptions
{
editor
?:
ICodeEditor
;
progress
?:
IProgressRunner
;
}
export
interface
IBulkEditResult
{
selection
:
Selection
;
ariaSummary
:
string
;
}
export
interface
IBulkEditService
{
_serviceBrand
:
any
;
apply
(
edit
:
WorkspaceEdit
,
options
:
IBulkEditOptions
):
TPromise
<
IBulkEditResult
>
;
}
src/vs/editor/contrib/codeAction/codeActionCommands.ts
浏览文件 @
727774d6
...
...
@@ -8,18 +8,14 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
ICodeEditor
}
from
'
vs/editor/browser/editorBrowser
'
;
import
{
EditorAction
,
EditorCommand
,
ServicesAccessor
}
from
'
vs/editor/browser/editorExtensions
'
;
import
{
BulkEdit
}
from
'
vs/editor/browser/services/bulkEdit
'
;
import
{
IEditorContribution
}
from
'
vs/editor/common/editorCommon
'
;
import
{
EditorContextKeys
}
from
'
vs/editor/common/editorContextKeys
'
;
import
{
CodeAction
}
from
'
vs/editor/common/modes
'
;
import
{
ITextModelService
}
from
'
vs/editor/common/services/resolverService
'
;
import
{
MessageController
}
from
'
vs/editor/contrib/message/messageController
'
;
import
*
as
nls
from
'
vs/nls
'
;
import
{
ICommandService
}
from
'
vs/platform/commands/common/commands
'
;
import
{
ContextKeyExpr
,
IContextKeyService
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
IContextMenuService
}
from
'
vs/platform/contextview/browser/contextView
'
;
import
{
IFileService
}
from
'
vs/platform/files/common/files
'
;
import
{
optional
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IKeybindingService
}
from
'
vs/platform/keybinding/common/keybinding
'
;
import
{
IMarkerService
}
from
'
vs/platform/markers/common/markers
'
;
import
{
CodeActionModel
,
CodeActionsComputeEvent
,
SUPPORTED_CODE_ACTIONS
}
from
'
./codeActionModel
'
;
...
...
@@ -27,6 +23,7 @@ import { CodeActionAutoApply, CodeActionFilter, CodeActionKind } from './codeAct
import
{
CodeActionContextMenu
}
from
'
./codeActionWidget
'
;
import
{
LightBulbWidget
}
from
'
./lightBulbWidget
'
;
import
{
escapeRegExpCharacters
}
from
'
vs/base/common/strings
'
;
import
{
IBulkEditService
}
from
'
../../browser/services/bulkEditService
'
;
function
contextKeyForSupportedActions
(
kind
:
CodeActionKind
)
{
return
ContextKeyExpr
.
regex
(
...
...
@@ -54,8 +51,7 @@ export class QuickFixController implements IEditorContribution {
@
ICommandService
private
readonly
_commandService
:
ICommandService
,
@
IContextMenuService
contextMenuService
:
IContextMenuService
,
@
IKeybindingService
private
readonly
_keybindingService
:
IKeybindingService
,
@
ITextModelService
private
readonly
_textModelService
:
ITextModelService
,
@
optional
(
IFileService
)
private
_fileService
:
IFileService
@
IBulkEditService
private
readonly
_bulkEditService
:
IBulkEditService
)
{
this
.
_editor
=
editor
;
this
.
_model
=
new
CodeActionModel
(
this
.
_editor
,
markerService
,
contextKeyService
);
...
...
@@ -131,19 +127,18 @@ export class QuickFixController implements IEditorContribution {
}
private
async
_onApplyCodeAction
(
action
:
CodeAction
):
TPromise
<
void
>
{
await
applyCodeAction
(
action
,
this
.
_
textModelService
,
this
.
_file
Service
,
this
.
_commandService
,
this
.
_editor
);
await
applyCodeAction
(
action
,
this
.
_
bulkEdit
Service
,
this
.
_commandService
,
this
.
_editor
);
}
}
export
async
function
applyCodeAction
(
action
:
CodeAction
,
textModelService
:
ITextModelService
,
fileService
:
IFileService
,
bulkEditService
:
IBulkEditService
,
commandService
:
ICommandService
,
editor
:
ICodeEditor
,
)
{
if
(
action
.
edit
)
{
await
BulkEdit
.
perform
(
action
.
edit
.
edits
,
textModelService
,
fileService
,
editor
);
await
bulkEditService
.
apply
(
action
.
edit
,
{
editor
}
);
}
if
(
action
.
command
)
{
await
commandService
.
executeCommand
(
action
.
command
.
id
,
...
action
.
command
.
arguments
);
...
...
@@ -332,4 +327,4 @@ export class OrganizeImportsAction extends EditorAction {
{
kind
:
CodeActionKind
.
SourceOrganizeImports
,
includeSourceActions
:
true
},
CodeActionAutoApply
.
IfSingle
);
}
}
\ No newline at end of file
}
src/vs/editor/contrib/rename/rename.ts
浏览文件 @
727774d6
...
...
@@ -9,18 +9,14 @@ import * as nls from 'vs/nls';
import
{
illegalArgument
}
from
'
vs/base/common/errors
'
;
import
{
KeyMod
,
KeyCode
}
from
'
vs/base/common/keyCodes
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
IFileService
}
from
'
vs/platform/files/common/files
'
;
import
{
RawContextKey
,
IContextKey
,
IContextKeyService
,
ContextKeyExpr
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
IProgressService
}
from
'
vs/platform/progress/common/progress
'
;
import
{
registerEditorAction
,
registerEditorContribution
,
ServicesAccessor
,
EditorAction
,
EditorCommand
,
registerEditorCommand
,
registerDefaultLanguageCommand
}
from
'
vs/editor/browser/editorExtensions
'
;
import
{
IEditorContribution
}
from
'
vs/editor/common/editorCommon
'
;
import
{
ITextModel
}
from
'
vs/editor/common/model
'
;
import
{
EditorContextKeys
}
from
'
vs/editor/common/editorContextKeys
'
;
import
{
BulkEdit
}
from
'
vs/editor/browser/services/bulkEdit
'
;
import
{
ICodeEditor
}
from
'
vs/editor/browser/editorBrowser
'
;
import
RenameInputField
from
'
./renameInputField
'
;
import
{
ITextModelService
}
from
'
vs/editor/common/services/resolverService
'
;
import
{
optional
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IThemeService
}
from
'
vs/platform/theme/common/themeService
'
;
import
{
asWinJsPromise
}
from
'
vs/base/common/async
'
;
import
{
WorkspaceEdit
,
RenameProviderRegistry
,
RenameProvider
,
RenameLocation
}
from
'
vs/editor/common/modes
'
;
...
...
@@ -31,6 +27,7 @@ import { MessageController } from 'vs/editor/contrib/message/messageController';
import
{
EditorState
,
CodeEditorStateFlag
}
from
'
vs/editor/browser/core/editorState
'
;
import
{
KeybindingsRegistry
}
from
'
vs/platform/keybinding/common/keybindingsRegistry
'
;
import
{
INotificationService
}
from
'
vs/platform/notification/common/notification
'
;
import
{
IBulkEditService
}
from
'
../../browser/services/bulkEditService
'
;
class
RenameSkeleton
{
...
...
@@ -111,11 +108,10 @@ class RenameController implements IEditorContribution {
constructor
(
private
editor
:
ICodeEditor
,
@
INotificationService
private
readonly
_notificationService
:
INotificationService
,
@
I
TextModelService
private
readonly
_textModelResolverService
:
ITextModel
Service
,
@
I
BulkEditService
private
readonly
_bulkEditService
:
IBulkEdit
Service
,
@
IProgressService
private
readonly
_progressService
:
IProgressService
,
@
IContextKeyService
contextKeyService
:
IContextKeyService
,
@
IThemeService
themeService
:
IThemeService
,
@
optional
(
IFileService
)
private
_fileService
:
IFileService
)
{
this
.
_renameInputField
=
new
RenameInputField
(
editor
,
themeService
);
this
.
_renameInputVisible
=
CONTEXT_RENAME_INPUT_VISIBLE
.
bindTo
(
contextKeyService
);
...
...
@@ -168,7 +164,6 @@ class RenameController implements IEditorContribution {
this
.
editor
.
focus
();
const
edit
=
new
BulkEdit
(
this
.
editor
,
null
,
this
.
_textModelResolverService
,
this
.
_fileService
);
const
state
=
new
EditorState
(
this
.
editor
,
CodeEditorStateFlag
.
Position
|
CodeEditorStateFlag
.
Value
|
CodeEditorStateFlag
.
Selection
|
CodeEditorStateFlag
.
Scroll
);
const
renameOperation
=
skeleton
.
provideRenameEdits
(
newNameOrFocusFlag
,
0
,
[],
Range
.
lift
(
loc
.
range
).
getStartPosition
()).
then
(
result
=>
{
...
...
@@ -180,14 +175,15 @@ class RenameController implements IEditorContribution {
}
return
undefined
;
}
edit
.
add
(
result
.
edits
);
return
edit
.
perform
().
then
(
selection
=>
{
if
(
selection
)
{
this
.
editor
.
setSelection
(
selection
);
return
this
.
_bulkEditService
.
apply
(
result
,
{
editor
:
this
.
editor
}).
then
(
result
=>
{
if
(
result
.
selection
)
{
this
.
editor
.
setSelection
(
result
.
selection
);
}
// alert
alert
(
nls
.
localize
(
'
aria
'
,
"
Successfully renamed '{0}' to '{1}'. Summary: {2}
"
,
loc
.
text
,
newNameOrFocusFlag
,
edit
.
ariaMessage
()));
if
(
result
.
ariaSummary
)
{
alert
(
nls
.
localize
(
'
aria
'
,
"
Successfully renamed '{0}' to '{1}'. Summary: {2}
"
,
loc
.
text
,
newNameOrFocusFlag
,
result
.
ariaSummary
));
}
});
},
err
=>
{
...
...
src/vs/editor/standalone/browser/simpleServices.ts
浏览文件 @
727774d6
...
...
@@ -36,12 +36,17 @@ import { ITelemetryService, ITelemetryInfo } from 'vs/platform/telemetry/common/
import
{
ResolvedKeybinding
,
Keybinding
,
createKeybinding
,
SimpleKeybinding
}
from
'
vs/base/common/keyCodes
'
;
import
{
ResolvedKeybindingItem
}
from
'
vs/platform/keybinding/common/resolvedKeybindingItem
'
;
import
{
OS
}
from
'
vs/base/common/platform
'
;
import
{
IRange
}
from
'
vs/editor/common/core/range
'
;
import
{
IRange
,
Range
}
from
'
vs/editor/common/core/range
'
;
import
{
ITextModel
}
from
'
vs/editor/common/model
'
;
import
{
INotificationService
,
INotification
,
INotificationHandle
,
NoOpNotification
,
IPromptChoice
}
from
'
vs/platform/notification/common/notification
'
;
import
{
IConfirmation
,
IConfirmationResult
,
IDialogService
,
IDialogOptions
}
from
'
vs/platform/dialogs/common/dialogs
'
;
import
{
IPosition
,
Position
as
Pos
}
from
'
vs/editor/common/core/position
'
;
import
{
isEditorConfigurationKey
,
isDiffEditorConfigurationKey
}
from
'
vs/editor/common/config/commonEditorConfig
'
;
import
{
IBulkEditService
,
IBulkEditOptions
,
IBulkEditResult
}
from
'
vs/editor/browser/services/bulkEditService
'
;
import
{
WorkspaceEdit
,
isResourceTextEdit
,
TextEdit
}
from
'
vs/editor/common/modes
'
;
import
{
IModelService
}
from
'
vs/editor/common/services/modelService
'
;
import
{
EditOperation
}
from
'
vs/editor/common/core/editOperation
'
;
import
{
localize
}
from
'
vs/nls
'
;
export
class
SimpleEditor
implements
IEditor
{
...
...
@@ -643,3 +648,44 @@ export function applyConfigurationValues(configurationService: IConfigurationSer
}
});
}
export
class
SimpleBulkEditService
implements
IBulkEditService
{
_serviceBrand
:
any
;
constructor
(
private
readonly
_modelService
:
IModelService
)
{
//
}
apply
(
workspaceEdit
:
WorkspaceEdit
,
options
:
IBulkEditOptions
):
TPromise
<
IBulkEditResult
>
{
let
edits
=
new
Map
<
ITextModel
,
TextEdit
[]
>
();
for
(
let
edit
of
workspaceEdit
.
edits
)
{
if
(
!
isResourceTextEdit
(
edit
))
{
return
TPromise
.
wrapError
(
new
Error
(
'
bad edit - only text edits are supported
'
));
}
let
model
=
this
.
_modelService
.
getModel
(
edit
.
resource
);
if
(
!
model
)
{
return
TPromise
.
wrapError
(
new
Error
(
'
bad edit - model not found
'
));
}
let
array
=
edits
.
get
(
model
);
if
(
!
array
)
{
array
=
[];
}
edits
.
set
(
model
,
array
.
concat
(
edit
.
edits
));
}
let
totalEdits
=
0
;
let
totalFiles
=
0
;
edits
.
forEach
((
edits
,
model
)
=>
{
model
.
applyEdits
(
edits
.
map
(
edit
=>
EditOperation
.
replaceMove
(
Range
.
lift
(
edit
.
range
),
edit
.
text
)));
totalFiles
+=
1
;
totalEdits
+=
edits
.
length
;
});
return
TPromise
.
as
({
selection
:
undefined
,
ariaSummary
:
localize
(
'
summary
'
,
'
Made {0} edits in {1} files
'
,
totalEdits
,
totalFiles
)
});
}
}
src/vs/editor/standalone/browser/standaloneServices.ts
浏览文件 @
727774d6
...
...
@@ -33,7 +33,7 @@ import { CodeEditorServiceImpl } from 'vs/editor/browser/services/codeEditorServ
import
{
SimpleConfigurationService
,
SimpleResourceConfigurationService
,
SimpleMenuService
,
SimpleProgressService
,
StandaloneCommandService
,
StandaloneKeybindingService
,
SimpleNotificationService
,
StandaloneTelemetryService
,
SimpleWorkspaceContextService
,
SimpleDialogService
StandaloneTelemetryService
,
SimpleWorkspaceContextService
,
SimpleDialogService
,
SimpleBulkEditService
}
from
'
vs/editor/standalone/browser/simpleServices
'
;
import
{
ContextKeyService
}
from
'
vs/platform/contextkey/browser/contextKeyService
'
;
import
{
IMenuService
}
from
'
vs/platform/actions/common/actions
'
;
...
...
@@ -43,6 +43,7 @@ import { ILogService, NullLogService } from 'vs/platform/log/common/log';
import
{
INotificationService
}
from
'
vs/platform/notification/common/notification
'
;
import
{
IDialogService
}
from
'
vs/platform/dialogs/common/dialogs
'
;
import
{
IListService
,
ListService
}
from
'
vs/platform/list/browser/listService
'
;
import
{
IBulkEditService
}
from
'
vs/editor/browser/services/bulkEditService
'
;
export
interface
IEditorContextViewService
extends
IContextViewService
{
dispose
():
void
;
...
...
@@ -192,6 +193,8 @@ export class DynamicStandaloneServices extends Disposable {
ensure
(
IContextMenuService
,
()
=>
this
.
_register
(
new
ContextMenuService
(
domElement
,
telemetryService
,
notificationService
,
contextViewService
)));
ensure
(
IMenuService
,
()
=>
new
SimpleMenuService
(
commandService
));
ensure
(
IBulkEditService
,
()
=>
new
SimpleBulkEditService
(
StaticServices
.
modelService
.
get
(
IModelService
)));
}
public
get
<
T
>
(
serviceId
:
ServiceIdentifier
<
T
>
):
T
{
...
...
src/vs/workbench/api/electron-browser/mainThreadDocumentsAndEditors.ts
浏览文件 @
727774d6
...
...
@@ -24,6 +24,7 @@ import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/un
import
{
IEditorGroupService
}
from
'
vs/workbench/services/group/common/groupService
'
;
import
{
isCodeEditor
,
isDiffEditor
,
ICodeEditor
}
from
'
vs/editor/browser/editorBrowser
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
{
IBulkEditService
}
from
'
vs/editor/browser/services/bulkEditService
'
;
namespace
mapset
{
...
...
@@ -310,14 +311,16 @@ export class MainThreadDocumentsAndEditors {
@
IFileService
fileService
:
IFileService
,
@
ITextModelService
textModelResolverService
:
ITextModelService
,
@
IUntitledEditorService
untitledEditorService
:
IUntitledEditorService
,
@
IEditorGroupService
editorGroupService
:
IEditorGroupService
@
IEditorGroupService
editorGroupService
:
IEditorGroupService
,
@
IBulkEditService
bulkEditService
:
IBulkEditService
,
)
{
this
.
_proxy
=
extHostContext
.
getProxy
(
ExtHostContext
.
ExtHostDocumentsAndEditors
);
const
mainThreadDocuments
=
new
MainThreadDocuments
(
this
,
extHostContext
,
this
.
_modelService
,
modeService
,
this
.
_textFileService
,
fileService
,
textModelResolverService
,
untitledEditorService
);
extHostContext
.
set
(
MainContext
.
MainThreadDocuments
,
mainThreadDocuments
);
const
mainThreadTextEditors
=
new
MainThreadTextEditors
(
this
,
extHostContext
,
codeEditorService
,
this
.
_workbenchEditorService
,
editorGroupService
,
textModelResolverService
,
fileService
,
this
.
_model
Service
);
const
mainThreadTextEditors
=
new
MainThreadTextEditors
(
this
,
extHostContext
,
codeEditorService
,
bulkEditService
,
this
.
_workbenchEditorService
,
editorGroup
Service
);
extHostContext
.
set
(
MainContext
.
MainThreadTextEditors
,
mainThreadTextEditors
);
// It is expected that the ctor of the state computer calls our `_onDelta`.
...
...
src/vs/workbench/api/electron-browser/mainThreadEditors.ts
浏览文件 @
727774d6
...
...
@@ -4,29 +4,24 @@
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
URI
,
{
UriComponents
}
from
'
vs/base/common/uri
'
;
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
disposed
}
from
'
vs/base/common/errors
'
;
import
{
IDisposable
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
{
equals
as
objectEquals
}
from
'
vs/base/common/objects
'
;
import
URI
,
{
UriComponents
}
from
'
vs/base/common/uri
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
IDecorationRenderOptions
,
IDecorationOptions
,
ILineChange
}
from
'
vs/editor/common/editorCommon
'
;
import
{
ISingleEditOperation
}
from
'
vs/editor/common/model
'
;
import
{
IBulkEditService
}
from
'
vs/editor/browser/services/bulkEditService
'
;
import
{
ICodeEditorService
}
from
'
vs/editor/browser/services/codeEditorService
'
;
import
{
IRange
}
from
'
vs/editor/common/core/range
'
;
import
{
ISelection
}
from
'
vs/editor/common/core/selection
'
;
import
{
IDecorationOptions
,
IDecorationRenderOptions
,
ILineChange
}
from
'
vs/editor/common/editorCommon
'
;
import
{
ISingleEditOperation
}
from
'
vs/editor/common/model
'
;
import
{
ITextEditorOptions
,
Position
as
EditorPosition
}
from
'
vs/platform/editor/common/editor
'
;
import
{
IApplyEditsOptions
,
ITextEditorConfigurationUpdate
,
IUndoStopOptions
,
TextEditorRevealType
,
WorkspaceEditDto
,
reviveWorkspaceEditDto
}
from
'
vs/workbench/api/node/extHost.protocol
'
;
import
{
IWorkbenchEditorService
}
from
'
vs/workbench/services/editor/common/editorService
'
;
import
{
IEditorGroupService
}
from
'
vs/workbench/services/group/common/groupService
'
;
import
{
Position
as
EditorPosition
,
ITextEditorOptions
}
from
'
vs/platform/editor/common/editor
'
;
import
{
MainThreadTextEditor
}
from
'
./mainThreadEditor
'
;
import
{
ITextEditorConfigurationUpdate
,
TextEditorRevealType
,
IApplyEditsOptions
,
IUndoStopOptions
,
WorkspaceEditDto
,
reviveWorkspaceEditDto
}
from
'
vs/workbench/api/node/extHost.protocol
'
;
import
{
ExtHostContext
,
ExtHostEditorsShape
,
IExtHostContext
,
ITextDocumentShowOptions
,
ITextEditorPositionData
,
MainThreadTextEditorsShape
}
from
'
../node/extHost.protocol
'
;
import
{
MainThreadDocumentsAndEditors
}
from
'
./mainThreadDocumentsAndEditors
'
;
import
{
equals
as
objectEquals
}
from
'
vs/base/common/objects
'
;
import
{
ExtHostContext
,
MainThreadTextEditorsShape
,
ExtHostEditorsShape
,
ITextDocumentShowOptions
,
ITextEditorPositionData
,
IExtHostContext
}
from
'
../node/extHost.protocol
'
;
import
{
IRange
}
from
'
vs/editor/common/core/range
'
;
import
{
ISelection
}
from
'
vs/editor/common/core/selection
'
;
import
{
ITextModelService
}
from
'
vs/editor/common/services/resolverService
'
;
import
{
IFileService
}
from
'
vs/platform/files/common/files
'
;
import
{
BulkEdit
}
from
'
vs/editor/browser/services/bulkEdit
'
;
import
{
IModelService
}
from
'
vs/editor/common/services/modelService
'
;
import
{
isCodeEditor
,
ICodeEditor
}
from
'
vs/editor/browser/editorBrowser
'
;
import
{
isResourceFileEdit
}
from
'
vs/editor/common/modes
'
;
import
{
MainThreadTextEditor
}
from
'
./mainThreadEditor
'
;
export
class
MainThreadTextEditors
implements
MainThreadTextEditorsShape
{
...
...
@@ -42,11 +37,9 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
documentsAndEditors
:
MainThreadDocumentsAndEditors
,
extHostContext
:
IExtHostContext
,
@
ICodeEditorService
private
readonly
_codeEditorService
:
ICodeEditorService
,
@
IBulkEditService
private
readonly
_bulkEditService
:
IBulkEditService
,
@
IWorkbenchEditorService
workbenchEditorService
:
IWorkbenchEditorService
,
@
IEditorGroupService
editorGroupService
:
IEditorGroupService
,
@
ITextModelService
private
readonly
_textModelResolverService
:
ITextModelService
,
@
IFileService
private
readonly
_fileService
:
IFileService
,
@
IModelService
private
readonly
_modelService
:
IModelService
,
)
{
this
.
_proxy
=
extHostContext
.
getProxy
(
ExtHostContext
.
ExtHostEditors
);
this
.
_documentsAndEditors
=
documentsAndEditors
;
...
...
@@ -209,31 +202,8 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
}
$tryApplyWorkspaceEdit
(
dto
:
WorkspaceEditDto
):
TPromise
<
boolean
>
{
const
{
edits
}
=
reviveWorkspaceEditDto
(
dto
);
// First check if loaded models were not changed in the meantime
for
(
let
i
=
0
,
len
=
edits
.
length
;
i
<
len
;
i
++
)
{
const
edit
=
edits
[
i
];
if
(
!
isResourceFileEdit
(
edit
)
&&
edit
.
modelVersionId
)
{
let
model
=
this
.
_modelService
.
getModel
(
edit
.
resource
);
if
(
model
&&
model
.
getVersionId
()
!==
edit
.
modelVersionId
)
{
// model changed in the meantime
return
TPromise
.
as
(
false
);
}
}
}
let
codeEditor
:
ICodeEditor
;
let
editor
=
this
.
_workbenchEditorService
.
getActiveEditor
();
if
(
editor
)
{
let
candidate
=
editor
.
getControl
();
if
(
isCodeEditor
(
candidate
))
{
codeEditor
=
candidate
;
}
}
return
BulkEdit
.
perform
(
edits
,
this
.
_textModelResolverService
,
this
.
_fileService
,
codeEditor
).
then
(()
=>
true
);
return
this
.
_bulkEditService
.
apply
({
edits
},
undefined
).
then
(()
=>
true
,
err
=>
false
);
}
$tryInsertSnippet
(
id
:
string
,
template
:
string
,
ranges
:
IRange
[],
opts
:
IUndoStopOptions
):
TPromise
<
boolean
>
{
...
...
src/vs/workbench/api/electron-browser/mainThreadSaveParticipant.ts
浏览文件 @
727774d6
...
...
@@ -30,14 +30,13 @@ import { isFalsyOrEmpty } from 'vs/base/common/arrays';
import
{
ILogService
}
from
'
vs/platform/log/common/log
'
;
import
{
shouldSynchronizeModel
}
from
'
vs/editor/common/services/modelService
'
;
import
{
SnippetController2
}
from
'
vs/editor/contrib/snippet/snippetController2
'
;
import
{
ITextModelService
}
from
'
vs/editor/common/services/resolverService
'
;
import
{
ICommandService
}
from
'
vs/platform/commands/common/commands
'
;
import
{
IFileService
}
from
'
vs/platform/files/common/files
'
;
import
{
CodeActionKind
}
from
'
vs/editor/contrib/codeAction/codeActionTrigger
'
;
import
{
CodeAction
}
from
'
vs/editor/common/modes
'
;
import
{
applyCodeAction
}
from
'
vs/editor/contrib/codeAction/codeActionCommands
'
;
import
{
getCodeActions
}
from
'
vs/editor/contrib/codeAction/codeAction
'
;
import
{
ICodeActionsOnSaveOptions
}
from
'
vs/editor/common/config/editorOptions
'
;
import
{
IBulkEditService
}
from
'
vs/editor/browser/services/bulkEditService
'
;
export
interface
ISaveParticipantParticipant
extends
ISaveParticipant
{
// progressMessage: string;
...
...
@@ -270,8 +269,7 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant {
class
CodeActionOnParticipant
implements
ISaveParticipant
{
constructor
(
@
ITextModelService
private
readonly
_textModelService
:
ITextModelService
,
@
IFileService
private
readonly
_fileService
:
IFileService
,
@
IBulkEditService
private
readonly
_bulkEditService
:
IBulkEditService
,
@
ICommandService
private
readonly
_commandService
:
ICommandService
,
@
ICodeEditorService
private
readonly
_codeEditorService
:
ICodeEditorService
,
@
IConfigurationService
private
readonly
_configurationService
:
IConfigurationService
...
...
@@ -309,7 +307,7 @@ class CodeActionOnParticipant implements ISaveParticipant {
private
async
applyCodeActions
(
actionsToRun
:
CodeAction
[],
editor
:
ICodeEditor
)
{
for
(
const
action
of
actionsToRun
)
{
await
applyCodeAction
(
action
,
this
.
_
textModelService
,
this
.
_file
Service
,
this
.
_commandService
,
editor
);
await
applyCodeAction
(
action
,
this
.
_
bulkEdit
Service
,
this
.
_commandService
,
editor
);
}
}
...
...
src/vs/workbench/parts/search/browser/replaceService.ts
浏览文件 @
727774d6
...
...
@@ -15,7 +15,6 @@ import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/edi
import
{
IModelService
}
from
'
vs/editor/common/services/modelService
'
;
import
{
IModeService
}
from
'
vs/editor/common/services/modeService
'
;
import
{
Match
,
FileMatch
,
FileMatchOrMatch
,
ISearchWorkbenchService
}
from
'
vs/workbench/parts/search/common/searchModel
'
;
import
{
BulkEdit
}
from
'
vs/editor/browser/services/bulkEdit
'
;
import
{
IProgressRunner
}
from
'
vs/platform/progress/common/progress
'
;
import
{
IDiffEditor
}
from
'
vs/editor/browser/editorBrowser
'
;
import
{
ITextModelService
,
ITextModelContentProvider
}
from
'
vs/editor/common/services/resolverService
'
;
...
...
@@ -23,10 +22,10 @@ import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import
{
ScrollType
}
from
'
vs/editor/common/editorCommon
'
;
import
{
ITextModel
}
from
'
vs/editor/common/model
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
IFileService
}
from
'
vs/platform/files/common/files
'
;
import
{
ResourceTextEdit
}
from
'
vs/editor/common/modes
'
;
import
{
createTextBufferFactoryFromSnapshot
}
from
'
vs/editor/common/model/textModel
'
;
import
{
ITextFileService
}
from
'
vs/workbench/services/textfile/common/textfiles
'
;
import
{
IBulkEditService
}
from
'
vs/editor/browser/services/bulkEditService
'
;
const
REPLACE_PREVIEW
=
'
replacePreview
'
;
...
...
@@ -95,10 +94,10 @@ export class ReplaceService implements IReplaceService {
public
_serviceBrand
:
any
;
constructor
(
@
IFileService
private
fileService
:
IFileService
,
@
ITextFileService
private
textFileService
:
ITextFileService
,
@
IEditorService
private
editorService
:
IWorkbenchEditorService
,
@
ITextModelService
private
textModelResolverService
:
ITextModelService
@
ITextModelService
private
textModelResolverService
:
ITextModelService
,
@
IBulkEditService
private
bulkEditorService
:
IBulkEditService
)
{
}
public
replace
(
match
:
Match
):
TPromise
<
any
>
;
...
...
@@ -108,8 +107,6 @@ export class ReplaceService implements IReplaceService {
const
edits
:
ResourceTextEdit
[]
=
[];
let
bulkEdit
=
new
BulkEdit
(
null
,
progress
,
this
.
textModelResolverService
,
this
.
fileService
);
if
(
arg
instanceof
Match
)
{
let
match
=
<
Match
>
arg
;
edits
.
push
(
this
.
createEdit
(
match
,
match
.
replaceString
,
resource
));
...
...
@@ -128,8 +125,8 @@ export class ReplaceService implements IReplaceService {
});
}
bulkEdit
.
add
(
edits
);
return
bulkEdit
.
perform
().
then
(()
=>
this
.
textFileService
.
saveAll
(
edits
.
map
(
e
=>
e
.
resource
)));
return
this
.
bulkEditorService
.
apply
({
edits
},
{
progress
}).
then
(()
=>
this
.
textFileService
.
saveAll
(
edits
.
map
(
e
=>
e
.
resource
))
);
}
public
openReplacePreview
(
element
:
FileMatchOrMatch
,
preserveFocus
?:
boolean
,
sideBySide
?:
boolean
,
pinned
?:
boolean
):
TPromise
<
any
>
{
...
...
src/vs/
editor/browser/services/bulkEdit
.ts
→
src/vs/
workbench/services/bulkEdit/electron-browser/bulkEditService
.ts
浏览文件 @
727774d6
...
...
@@ -4,40 +4,40 @@
*--------------------------------------------------------------------------------------------*/
'
use strict
'
;
import
*
as
nls
from
'
vs/nls
'
;
import
{
IDisposable
,
dispose
,
IReference
}
from
'
vs/base/common/lifecycle
'
;
import
{
getPathLabel
}
from
'
vs/base/common/labels
'
;
import
{
IDisposable
,
IReference
,
dispose
}
from
'
vs/base/common/lifecycle
'
;
import
URI
from
'
vs/base/common/uri
'
;
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
I
TextModelService
,
ITextEditorModel
}
from
'
vs/editor/common/services/resolverService
'
;
import
{
I
FileService
,
FileChangeType
}
from
'
vs/platform/files/common/files
'
;
import
{
I
CodeEditor
,
isCodeEditor
}
from
'
vs/editor/browser/editorBrowser
'
;
import
{
I
BulkEditOptions
,
IBulkEditResult
,
IBulkEditService
}
from
'
vs/editor/browser/services/bulkEditService
'
;
import
{
EditOperation
}
from
'
vs/editor/common/core/editOperation
'
;
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
{
Selection
}
from
'
vs/editor/common/core/selection
'
;
import
{
IIdentifiedSingleEditOperation
,
ITextModel
,
EndOfLineSequence
}
from
'
vs/editor/common/model
'
;
import
{
IProgressRunner
,
emptyProgressRunner
,
IProgress
}
from
'
vs/platform/progress/common/progress
'
;
import
{
ICodeEditor
}
from
'
vs/editor/browser/editorBrowser
'
;
import
{
optional
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
ResourceTextEdit
,
ResourceFileEdit
,
isResourceFileEdit
,
isResourceTextEdit
}
from
'
vs/editor/common/modes
'
;
import
{
getPathLabel
}
from
'
vs/base/common/labels
'
;
import
{
EndOfLineSequence
,
IIdentifiedSingleEditOperation
,
ITextModel
}
from
'
vs/editor/common/model
'
;
import
{
ResourceFileEdit
,
ResourceTextEdit
,
WorkspaceEdit
,
isResourceFileEdit
,
isResourceTextEdit
}
from
'
vs/editor/common/modes
'
;
import
{
IModelService
}
from
'
vs/editor/common/services/modelService
'
;
import
{
ITextEditorModel
,
ITextModelService
}
from
'
vs/editor/common/services/resolverService
'
;
import
{
localize
}
from
'
vs/nls
'
;
import
{
FileChangeType
,
IFileService
}
from
'
vs/platform/files/common/files
'
;
import
{
registerSingleton
}
from
'
vs/platform/instantiation/common/extensions
'
;
import
{
IProgress
,
IProgressRunner
,
emptyProgressRunner
}
from
'
vs/platform/progress/common/progress
'
;
import
{
IWorkbenchEditorService
}
from
'
vs/workbench/services/editor/common/editorService
'
;
abstract
class
Recording
{
abstract
class
I
Recording
{
static
start
(
fileService
:
IFileService
):
Recording
{
static
start
(
fileService
:
IFileService
):
IRecording
{
const
_changes
=
new
Set
<
string
>
();
let
_changes
=
new
Set
<
string
>
();
let
stop
:
IDisposable
;
if
(
fileService
)
{
// watch only when there is a fileservice available
stop
=
fileService
.
onFileChanges
(
event
=>
{
for
(
const
change
of
event
.
changes
)
{
if
(
change
.
type
===
FileChangeType
.
UPDATED
)
{
_changes
.
add
(
change
.
resource
.
toString
());
}
stop
=
fileService
.
onFileChanges
(
event
=>
{
for
(
const
change
of
event
.
changes
)
{
if
(
change
.
type
===
FileChangeType
.
UPDATED
)
{
_changes
.
add
(
change
.
resource
.
toString
());
}
}
);
}
}
}
);
return
{
stop
()
{
return
dispose
(
stop
);
},
...
...
@@ -258,12 +258,6 @@ export type Edit = ResourceFileEdit | ResourceTextEdit;
export
class
BulkEdit
{
static
perform
(
edits
:
Edit
[],
textModelService
:
ITextModelService
,
fileService
:
IFileService
,
editor
:
ICodeEditor
):
TPromise
<
any
>
{
const
edit
=
new
BulkEdit
(
editor
,
null
,
textModelService
,
fileService
);
edit
.
add
(
edits
);
return
edit
.
perform
();
}
private
_edits
:
Edit
[]
=
[];
private
_editor
:
ICodeEditor
;
private
_progress
:
IProgressRunner
;
...
...
@@ -272,7 +266,7 @@ export class BulkEdit {
editor
:
ICodeEditor
,
progress
:
IProgressRunner
,
@
ITextModelService
private
readonly
_textModelService
:
ITextModelService
,
@
optional
(
IFileService
)
private
_fileService
:
IFileService
@
IFileService
private
readonly
_fileService
:
IFileService
)
{
this
.
_editor
=
editor
;
this
.
_progress
=
progress
||
emptyProgressRunner
;
...
...
@@ -290,11 +284,11 @@ export class BulkEdit {
const
editCount
=
this
.
_edits
.
reduce
((
prev
,
cur
)
=>
isResourceFileEdit
(
cur
)
?
prev
:
prev
+
cur
.
edits
.
length
,
0
);
const
resourceCount
=
this
.
_edits
.
length
;
if
(
editCount
===
0
)
{
return
nls
.
localize
(
'
summary.0
'
,
"
Made no edits
"
);
return
localize
(
'
summary.0
'
,
"
Made no edits
"
);
}
else
if
(
editCount
>
1
&&
resourceCount
>
1
)
{
return
nls
.
localize
(
'
summary.nm
'
,
"
Made {0} text edits in {1} files
"
,
editCount
,
resourceCount
);
return
localize
(
'
summary.nm
'
,
"
Made {0} text edits in {1} files
"
,
editCount
,
resourceCount
);
}
else
{
return
nls
.
localize
(
'
summary.n0
'
,
"
Made {0} text edits in one file
"
,
editCount
,
resourceCount
);
return
localize
(
'
summary.n0
'
,
"
Made {0} text edits in one file
"
,
editCount
,
resourceCount
);
}
}
...
...
@@ -358,7 +352,7 @@ export class BulkEdit {
private
async
_performTextEdits
(
edits
:
ResourceTextEdit
[],
progress
:
IProgress
<
void
>
):
TPromise
<
Selection
>
{
const
recording
=
I
Recording
.
start
(
this
.
_fileService
);
const
recording
=
Recording
.
start
(
this
.
_fileService
);
const
model
=
new
BulkEditModel
(
this
.
_textModelService
,
this
.
_editor
,
edits
,
progress
);
await
model
.
prepare
();
...
...
@@ -371,7 +365,7 @@ export class BulkEdit {
if
(
conflicts
.
length
>
0
)
{
model
.
dispose
();
throw
new
Error
(
nls
.
localize
(
'
conflict
'
,
"
These files have changed in the meantime: {0}
"
,
conflicts
.
join
(
'
,
'
)));
throw
new
Error
(
localize
(
'
conflict
'
,
"
These files have changed in the meantime: {0}
"
,
conflicts
.
join
(
'
,
'
)));
}
const
selection
=
await
model
.
apply
();
...
...
@@ -379,3 +373,59 @@ export class BulkEdit {
return
selection
;
}
}
export
class
BulkEditService
implements
IBulkEditService
{
_serviceBrand
:
any
;
constructor
(
@
IModelService
private
readonly
_modelService
:
IModelService
,
@
IWorkbenchEditorService
private
readonly
_workbenchEditorService
:
IWorkbenchEditorService
,
@
ITextModelService
private
readonly
_textModelService
:
ITextModelService
,
@
IFileService
private
readonly
_fileService
:
IFileService
)
{
}
apply
(
edit
:
WorkspaceEdit
,
options
:
IBulkEditOptions
=
{}):
TPromise
<
IBulkEditResult
>
{
let
{
edits
}
=
edit
;
let
codeEditor
=
options
.
editor
;
// First check if loaded models were not changed in the meantime
for
(
let
i
=
0
,
len
=
edits
.
length
;
i
<
len
;
i
++
)
{
const
edit
=
edits
[
i
];
if
(
!
isResourceFileEdit
(
edit
)
&&
typeof
edit
.
modelVersionId
===
'
number
'
)
{
let
model
=
this
.
_modelService
.
getModel
(
edit
.
resource
);
if
(
model
&&
model
.
getVersionId
()
!==
edit
.
modelVersionId
)
{
// model changed in the meantime
return
TPromise
.
wrapError
(
new
Error
(
`
${
model
.
uri
.
toString
()}
has changed in the meantime`
));
}
}
}
// try to find code editor
// todo@joh, prefer edit that gets edited
if
(
!
codeEditor
)
{
let
editor
=
this
.
_workbenchEditorService
.
getActiveEditor
();
if
(
editor
)
{
let
candidate
=
editor
.
getControl
();
if
(
isCodeEditor
(
candidate
))
{
codeEditor
=
candidate
;
}
}
}
const
bulkEdit
=
new
BulkEdit
(
options
.
editor
,
options
.
progress
,
this
.
_textModelService
,
this
.
_fileService
);
bulkEdit
.
add
(
edits
);
return
bulkEdit
.
perform
().
then
(
selection
=>
{
return
{
selection
,
ariaSummary
:
bulkEdit
.
ariaMessage
()
};
});
}
}
registerSingleton
(
IBulkEditService
,
BulkEditService
);
src/vs/workbench/test/electron-browser/api/mainThreadEditors.test.ts
浏览文件 @
727774d6
...
...
@@ -27,6 +27,7 @@ import { TestFileService } from 'vs/workbench/test/workbenchTestServices';
import
{
TPromise
}
from
'
vs/base/common/winjs.base
'
;
import
{
IFileStat
}
from
'
vs/platform/files/common/files
'
;
import
{
ResourceTextEdit
}
from
'
vs/editor/common/modes
'
;
import
{
BulkEditService
}
from
'
../../../services/bulkEdit/electron-browser/bulkEditService
'
;
suite
(
'
MainThreadEditors
'
,
()
=>
{
...
...
@@ -80,6 +81,8 @@ suite('MainThreadEditors', () => {
onEditorGroupMoved
=
Event
.
None
;
};
const
bulkEditService
=
new
BulkEditService
(
modelService
,
workbenchEditorService
,
null
,
fileService
);
const
rpcProtocol
=
new
TestRPCProtocol
();
rpcProtocol
.
set
(
ExtHostContext
.
ExtHostDocuments
,
new
class
extends
mock
<
ExtHostDocumentsShape
>
()
{
$acceptModelChanged
():
void
{
...
...
@@ -101,17 +104,16 @@ suite('MainThreadEditors', () => {
null
,
null
,
editorGroupService
,
bulkEditService
,
);
editors
=
new
MainThreadTextEditors
(
documentAndEditor
,
SingleProxyRPCProtocol
(
null
),
codeEditorService
,
bulkEditService
,
workbenchEditorService
,
editorGroupService
,
null
,
fileService
,
modelService
);
});
...
...
src/vs/workbench/workbench.main.ts
浏览文件 @
727774d6
...
...
@@ -131,3 +131,6 @@ import 'vs/workbench/parts/themes/test/electron-browser/themes.test.contribution
import
'
vs/workbench/parts/watermark/electron-browser/watermark
'
;
import
'
vs/workbench/parts/welcome/overlay/browser/welcomeOverlay
'
;
// services
import
'
vs/workbench/services/bulkEdit/electron-browser/bulkEditService
'
;
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录