Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/mergeEditor/electron-browser/devCommands.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import { VSBuffer } from '../../../../base/common/buffer.js';
7
import { Codicon } from '../../../../base/common/codicons.js';
8
import { randomPath } from '../../../../base/common/extpath.js';
9
import { URI } from '../../../../base/common/uri.js';
10
import { ILanguageService } from '../../../../editor/common/languages/language.js';
11
import { localize, localize2 } from '../../../../nls.js';
12
import { ILocalizedString } from '../../../../platform/action/common/action.js';
13
import { Action2, IAction2Options } from '../../../../platform/actions/common/actions.js';
14
import { IClipboardService } from '../../../../platform/clipboard/common/clipboardService.js';
15
import { INativeEnvironmentService } from '../../../../platform/environment/common/environment.js';
16
import { IFileService } from '../../../../platform/files/common/files.js';
17
import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';
18
import { IQuickInputService } from '../../../../platform/quickinput/common/quickInput.js';
19
import { IResourceMergeEditorInput } from '../../../common/editor.js';
20
import { MergeEditor } from '../browser/view/mergeEditor.js';
21
import { MergeEditorViewModel } from '../browser/view/viewModel.js';
22
import { MergeEditorContents } from '../common/mergeEditor.js';
23
import { IEditorService } from '../../../services/editor/common/editorService.js';
24
25
const MERGE_EDITOR_CATEGORY: ILocalizedString = localize2('mergeEditor', 'Merge Editor (Dev)');
26
27
export class MergeEditorOpenContentsFromJSON extends Action2 {
28
constructor() {
29
super({
30
id: 'merge.dev.openContentsJson',
31
category: MERGE_EDITOR_CATEGORY,
32
title: localize2('merge.dev.openState', "Open Merge Editor State from JSON"),
33
icon: Codicon.layoutCentered,
34
f1: true,
35
});
36
}
37
38
async run(accessor: ServicesAccessor, args?: { data?: MergeEditorContents; resultState?: 'initial' | 'current' }): Promise<void> {
39
const quickInputService = accessor.get(IQuickInputService);
40
const clipboardService = accessor.get(IClipboardService);
41
const editorService = accessor.get(IEditorService);
42
const languageService = accessor.get(ILanguageService);
43
const env = accessor.get(INativeEnvironmentService);
44
const fileService = accessor.get(IFileService);
45
46
if (!args) {
47
args = {};
48
}
49
50
let content: MergeEditorContents;
51
if (!args.data) {
52
const result = await quickInputService.input({
53
prompt: localize('mergeEditor.enterJSON', 'Enter JSON'),
54
value: await clipboardService.readText(),
55
});
56
if (result === undefined) {
57
return;
58
}
59
content =
60
result !== ''
61
? JSON.parse(result)
62
: { base: '', input1: '', input2: '', result: '', languageId: 'plaintext' };
63
} else {
64
content = args.data;
65
}
66
67
const targetDir = URI.joinPath(env.tmpDir, randomPath());
68
69
const extension = languageService.getExtensions(content.languageId)[0] || '';
70
71
const baseUri = URI.joinPath(targetDir, `/base${extension}`);
72
const input1Uri = URI.joinPath(targetDir, `/input1${extension}`);
73
const input2Uri = URI.joinPath(targetDir, `/input2${extension}`);
74
const resultUri = URI.joinPath(targetDir, `/result${extension}`);
75
const initialResultUri = URI.joinPath(targetDir, `/initialResult${extension}`);
76
77
async function writeFile(uri: URI, content: string): Promise<void> {
78
await fileService.writeFile(uri, VSBuffer.fromString(content));
79
}
80
81
const shouldOpenInitial = await promptOpenInitial(quickInputService, args.resultState);
82
83
await Promise.all([
84
writeFile(baseUri, content.base),
85
writeFile(input1Uri, content.input1),
86
writeFile(input2Uri, content.input2),
87
writeFile(resultUri, shouldOpenInitial ? (content.initialResult || '') : content.result),
88
writeFile(initialResultUri, content.initialResult || ''),
89
]);
90
91
const input: IResourceMergeEditorInput = {
92
base: { resource: baseUri },
93
input1: { resource: input1Uri, label: 'Input 1', description: 'Input 1', detail: '(from JSON)' },
94
input2: { resource: input2Uri, label: 'Input 2', description: 'Input 2', detail: '(from JSON)' },
95
result: { resource: resultUri },
96
};
97
editorService.openEditor(input);
98
}
99
}
100
101
async function promptOpenInitial(quickInputService: IQuickInputService, resultStateOverride?: 'initial' | 'current') {
102
if (resultStateOverride) {
103
return resultStateOverride === 'initial';
104
}
105
const result = await quickInputService.pick([{ label: 'result', result: false }, { label: 'initial result', result: true }], { canPickMany: false });
106
return result?.result;
107
}
108
109
abstract class MergeEditorAction extends Action2 {
110
constructor(desc: Readonly<IAction2Options>) {
111
super(desc);
112
}
113
114
run(accessor: ServicesAccessor): void {
115
const { activeEditorPane } = accessor.get(IEditorService);
116
if (activeEditorPane instanceof MergeEditor) {
117
const vm = activeEditorPane.viewModel.get();
118
if (!vm) {
119
return;
120
}
121
this.runWithViewModel(vm, accessor);
122
}
123
}
124
125
abstract runWithViewModel(viewModel: MergeEditorViewModel, accessor: ServicesAccessor): void;
126
}
127
128
export class OpenSelectionInTemporaryMergeEditor extends MergeEditorAction {
129
constructor() {
130
super({
131
id: 'merge.dev.openSelectionInTemporaryMergeEditor',
132
category: MERGE_EDITOR_CATEGORY,
133
title: localize2('merge.dev.openSelectionInTemporaryMergeEditor', "Open Selection In Temporary Merge Editor"),
134
icon: Codicon.layoutCentered,
135
f1: true,
136
});
137
}
138
139
override async runWithViewModel(viewModel: MergeEditorViewModel, accessor: ServicesAccessor) {
140
const rangesInBase = viewModel.selectionInBase.get()?.rangesInBase;
141
if (!rangesInBase || rangesInBase.length === 0) {
142
return;
143
}
144
145
const base = rangesInBase
146
.map((r) =>
147
viewModel.model.base.getValueInRange(
148
r
149
)
150
)
151
.join('\n');
152
153
const input1 = rangesInBase
154
.map((r) =>
155
viewModel.inputCodeEditorView1.editor.getModel()!.getValueInRange(
156
viewModel.model.translateBaseRangeToInput(1, r)
157
)
158
)
159
.join('\n');
160
161
const input2 = rangesInBase
162
.map((r) =>
163
viewModel.inputCodeEditorView2.editor.getModel()!.getValueInRange(
164
viewModel.model.translateBaseRangeToInput(2, r)
165
)
166
)
167
.join('\n');
168
169
const result = rangesInBase
170
.map((r) =>
171
viewModel.resultCodeEditorView.editor.getModel()!.getValueInRange(
172
viewModel.model.translateBaseRangeToResult(r)
173
)
174
)
175
.join('\n');
176
177
new MergeEditorOpenContentsFromJSON().run(accessor, {
178
data: {
179
base,
180
input1,
181
input2,
182
result,
183
languageId: viewModel.resultCodeEditorView.editor.getModel()!.getLanguageId()
184
}
185
});
186
}
187
}
188
189