Skip to content

Commit 8399f4a

Browse files
committed
Have 'Format Document' and 'Format Document With...' at the same time, show message when formatting document with first provider, microsoft#41882
1 parent c98431e commit 8399f4a

4 files changed

Lines changed: 76 additions & 56 deletions

File tree

src/vs/editor/contrib/format/format.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ import { IModelService } from 'vs/editor/common/services/modelService';
2222
import { FormattingEdit } from 'vs/editor/contrib/format/formattingEdit';
2323
import * as nls from 'vs/nls';
2424
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
25+
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
26+
import { IStatusbarService } from 'vs/platform/statusbar/common/statusbar';
27+
import { ILabelService } from 'vs/platform/label/common/label';
2528

2629
export function alertFormattingEdits(edits: ISingleEditOperation[]): void {
2730

@@ -83,6 +86,32 @@ export function getRealAndSyntheticDocumentFormattersOrdered(model: ITextModel):
8386
return result;
8487
}
8588

89+
export async function formatDocumentRangeWithFirstProvider(
90+
accessor: ServicesAccessor,
91+
editorOrModel: ITextModel | IActiveCodeEditor,
92+
range: Range,
93+
token: CancellationToken
94+
): Promise<boolean> {
95+
96+
const instaService = accessor.get(IInstantiationService);
97+
const statusBarService = accessor.get(IStatusbarService);
98+
const labelService = accessor.get(ILabelService);
99+
100+
const model = isCodeEditor(editorOrModel) ? editorOrModel.getModel() : editorOrModel;
101+
const [best, ...rest] = DocumentRangeFormattingEditProviderRegistry.ordered(model);
102+
if (!best) {
103+
return false;
104+
}
105+
const ret = await instaService.invokeFunction(formatDocumentRangeWithProvider, best, editorOrModel, range, token);
106+
if (rest.length > 0) {
107+
statusBarService.setStatusMessage(
108+
nls.localize('random.pick', "$(tasklist) Formatted '{0}' with '{1}'", labelService.getUriLabel(model.uri, { relative: true }), best.displayName),
109+
5 * 1000
110+
);
111+
}
112+
return ret;
113+
}
114+
86115
export async function formatDocumentRangeWithProvider(
87116
accessor: ServicesAccessor,
88117
provider: DocumentRangeFormattingEditProvider,
@@ -152,6 +181,31 @@ export async function formatDocumentRangeWithProvider(
152181
return true;
153182
}
154183

184+
export async function formatDocumentWithFirstProvider(
185+
accessor: ServicesAccessor,
186+
editorOrModel: ITextModel | IActiveCodeEditor,
187+
token: CancellationToken
188+
): Promise<boolean> {
189+
190+
const instaService = accessor.get(IInstantiationService);
191+
const statusBarService = accessor.get(IStatusbarService);
192+
const labelService = accessor.get(ILabelService);
193+
194+
const model = isCodeEditor(editorOrModel) ? editorOrModel.getModel() : editorOrModel;
195+
const [best, ...rest] = getRealAndSyntheticDocumentFormattersOrdered(model);
196+
if (!best) {
197+
return false;
198+
}
199+
const ret = await instaService.invokeFunction(formatDocumentWithProvider, best, editorOrModel, token);
200+
if (rest.length > 0) {
201+
statusBarService.setStatusMessage(
202+
nls.localize('random.pick', "$(tasklist) Formatted '{0}' with '{1}'", labelService.getUriLabel(model.uri, { relative: true }), best.displayName),
203+
5 * 1000
204+
);
205+
}
206+
return ret;
207+
}
208+
155209
export async function formatDocumentWithProvider(
156210
accessor: ServicesAccessor,
157211
provider: DocumentFormattingEditProvider,

src/vs/editor/contrib/format/formatActions.ts

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import * as editorCommon from 'vs/editor/common/editorCommon';
1616
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
1717
import { DocumentRangeFormattingEditProviderRegistry, OnTypeFormattingEditProviderRegistry } from 'vs/editor/common/modes';
1818
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
19-
import { getOnTypeFormattingEdits, formatDocumentWithProvider, formatDocumentRangeWithProvider, alertFormattingEdits, getRealAndSyntheticDocumentFormattersOrdered } from 'vs/editor/contrib/format/format';
19+
import { getOnTypeFormattingEdits, alertFormattingEdits, formatDocumentRangeWithFirstProvider, formatDocumentWithFirstProvider } from 'vs/editor/contrib/format/format';
2020
import { FormattingEdit } from 'vs/editor/contrib/format/formattingEdit';
2121
import * as nls from 'vs/nls';
2222
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
@@ -211,12 +211,7 @@ class FormatOnPaste implements editorCommon.IEditorContribution {
211211
if (this.editor.getSelections().length > 1) {
212212
return;
213213
}
214-
const provider = DocumentRangeFormattingEditProviderRegistry.ordered(this.editor.getModel());
215-
if (provider.length !== 1) {
216-
// print status in n>1 case?
217-
return;
218-
}
219-
this._instantiationService.invokeFunction(formatDocumentRangeWithProvider, provider[0], this.editor, range, CancellationToken.None).catch(onUnexpectedError);
214+
this._instantiationService.invokeFunction(formatDocumentRangeWithFirstProvider, this.editor, range, CancellationToken.None).catch(onUnexpectedError);
220215
}
221216
}
222217

@@ -227,7 +222,7 @@ class FormatDocumentAction extends EditorAction {
227222
id: 'editor.action.formatDocument',
228223
label: nls.localize('formatDocument.label', "Format Document"),
229224
alias: 'Format Document',
230-
precondition: ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasDocumentFormattingProvider, EditorContextKeys.hasMultipleDocumentFormattingProvider.toNegated()),
225+
precondition: ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasDocumentFormattingProvider),
231226
kbOpts: {
232227
kbExpr: ContextKeyExpr.and(EditorContextKeys.editorTextFocus, EditorContextKeys.hasDocumentFormattingProvider),
233228
primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_F,
@@ -243,14 +238,9 @@ class FormatDocumentAction extends EditorAction {
243238
}
244239

245240
async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {
246-
if (!editor.hasModel()) {
247-
return;
248-
}
249-
const instaService = accessor.get(IInstantiationService);
250-
const model = editor.getModel();
251-
const [provider] = getRealAndSyntheticDocumentFormattersOrdered(model);
252-
if (provider) {
253-
await instaService.invokeFunction(formatDocumentWithProvider, provider, editor, CancellationToken.None);
241+
if (editor.hasModel()) {
242+
const instaService = accessor.get(IInstantiationService);
243+
await instaService.invokeFunction(formatDocumentWithFirstProvider, editor, CancellationToken.None);
254244
}
255245
}
256246
}
@@ -262,7 +252,7 @@ class FormatSelectionAction extends EditorAction {
262252
id: 'editor.action.formatSelection',
263253
label: nls.localize('formatSelection.label', "Format Selection"),
264254
alias: 'Format Code',
265-
precondition: ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasDocumentSelectionFormattingProvider, EditorContextKeys.hasMultipleDocumentSelectionFormattingProvider.toNegated()),
255+
precondition: ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasDocumentSelectionFormattingProvider),
266256
kbOpts: {
267257
kbExpr: ContextKeyExpr.and(EditorContextKeys.editorTextFocus, EditorContextKeys.hasDocumentSelectionFormattingProvider),
268258
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_F),
@@ -281,14 +271,12 @@ class FormatSelectionAction extends EditorAction {
281271
return;
282272
}
283273
const instaService = accessor.get(IInstantiationService);
284-
const [best] = DocumentRangeFormattingEditProviderRegistry.ordered(editor.getModel());
285-
if (best) {
286-
let range: Range = editor.getSelection();
287-
if (range.isEmpty()) {
288-
range = new Range(range.startLineNumber, 1, range.startLineNumber, editor.getModel().getLineMaxColumn(range.startLineNumber));
289-
}
290-
await instaService.invokeFunction(formatDocumentRangeWithProvider, best, editor, range, CancellationToken.None);
274+
const model = editor.getModel();
275+
let range: Range = editor.getSelection();
276+
if (range.isEmpty()) {
277+
range = new Range(range.startLineNumber, 1, range.startLineNumber, model.getLineMaxColumn(range.startLineNumber));
291278
}
279+
await instaService.invokeFunction(formatDocumentRangeWithFirstProvider, editor, range, CancellationToken.None);
292280
}
293281
}
294282

src/vs/workbench/api/browser/mainThreadSaveParticipant.ts

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { shouldSynchronizeModel } from 'vs/editor/common/services/modelService';
2121
import { getCodeActions } from 'vs/editor/contrib/codeAction/codeAction';
2222
import { applyCodeAction } from 'vs/editor/contrib/codeAction/codeActionCommands';
2323
import { CodeActionKind } from 'vs/editor/contrib/codeAction/codeActionTrigger';
24-
import { getRealAndSyntheticDocumentFormattersOrdered, formatDocumentWithProvider } from 'vs/editor/contrib/format/format';
24+
import { formatDocumentWithFirstProvider } from 'vs/editor/contrib/format/format';
2525
import { SnippetController2 } from 'vs/editor/contrib/snippet/snippetController2';
2626
import { localize } from 'vs/nls';
2727
import { ICommandService } from 'vs/platform/commands/common/commands';
@@ -227,24 +227,15 @@ class FormatOnSaveParticipant implements ISaveParticipantParticipant {
227227

228228
return new Promise<any>((resolve, reject) => {
229229
const source = new CancellationTokenSource();
230+
const timeout = this._configurationService.getValue<number>('editor.formatOnSaveTimeout', overrides);
231+
const request = this._instantiationService.invokeFunction(formatDocumentWithFirstProvider, model, source.token);
230232

231-
const provider = getRealAndSyntheticDocumentFormattersOrdered(model);
232-
if (provider.length !== 1) {
233-
// print message for >1 case?
234-
resolve();
233+
setTimeout(() => {
234+
reject(localize('timeout.formatOnSave', "Aborted format on save after {0}ms", timeout));
235+
source.cancel();
236+
}, timeout);
235237

236-
} else {
237-
// having 1 formatter -> go for it
238-
const timeout = this._configurationService.getValue<number>('editor.formatOnSaveTimeout', overrides);
239-
const request = this._instantiationService.invokeFunction(formatDocumentWithProvider, provider[0], model, source.token);
240-
241-
setTimeout(() => {
242-
reject(localize('timeout.formatOnSave', "Aborted format on save after {0}ms", timeout));
243-
source.cancel();
244-
}, timeout);
245-
246-
request.then(resolve, reject);
247-
}
238+
request.then(resolve, reject);
248239
});
249240
}
250241
}

src/vs/workbench/contrib/format/browser/formatActionsMultiple.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,12 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes';
76
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
87
import { EditorAction, registerEditorAction, ServicesAccessor } from 'vs/editor/browser/editorExtensions';
98
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
109
import { DocumentRangeFormattingEditProviderRegistry } from 'vs/editor/common/modes';
1110
import * as nls from 'vs/nls';
1211
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
13-
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
1412
import { IQuickInputService, IQuickPickItem, IQuickInputButton } from 'vs/platform/quickinput/common/quickInput';
1513
import { CancellationToken } from 'vs/base/common/cancellation';
1614
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
@@ -55,15 +53,9 @@ registerEditorAction(class FormatDocumentMultipleAction extends EditorAction {
5553
constructor() {
5654
super({
5755
id: 'editor.action.formatDocument.multiple',
58-
label: nls.localize('formatDocument.label.multiple', "Format Document..."),
56+
label: nls.localize('formatDocument.label.multiple', "Format Document With..."),
5957
alias: 'Format Document...',
6058
precondition: ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasMultipleDocumentFormattingProvider),
61-
kbOpts: {
62-
kbExpr: EditorContextKeys.editorTextFocus,
63-
primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_F,
64-
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_I },
65-
weight: KeybindingWeight.EditorContrib,
66-
},
6759
menuOpts: {
6860
group: '1_modification',
6961
order: 1.3
@@ -110,14 +102,9 @@ registerEditorAction(class FormatSelectionMultipleAction extends EditorAction {
110102
constructor() {
111103
super({
112104
id: 'editor.action.formatSelection.multiple',
113-
label: nls.localize('formatSelection.label.multiple', "Format Selection..."),
105+
label: nls.localize('formatSelection.label.multiple', "Format Selection With..."),
114106
alias: 'Format Code...',
115107
precondition: ContextKeyExpr.and(ContextKeyExpr.and(EditorContextKeys.writable), EditorContextKeys.hasMultipleDocumentSelectionFormattingProvider),
116-
kbOpts: {
117-
kbExpr: EditorContextKeys.editorTextFocus,
118-
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_F),
119-
weight: KeybindingWeight.EditorContrib
120-
},
121108
menuOpts: {
122109
when: ContextKeyExpr.and(EditorContextKeys.hasNonEmptySelection),
123110
group: '1_modification',

0 commit comments

Comments
 (0)