Skip to content

Commit 9ce3f2c

Browse files
committed
rename provider as support
1 parent a7ff9cd commit 9ce3f2c

6 files changed

Lines changed: 204 additions & 114 deletions

File tree

src/vs/editor/contrib/rename/browser/rename2.ts

Lines changed: 5 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {IKeybindingService, IKeybindingContextKey} from 'vs/platform/keybinding/
2525
import {IEventService} from 'vs/platform/event/common/event';
2626
import {IEditorService} from 'vs/platform/editor/common/editor';
2727
import {KeyMod, KeyCode} from 'vs/base/common/keyCodes';
28-
import {RenameRegistry} from '../common/rename';
28+
import {RenameRegistry, rename} from '../common/rename';
2929

3030
export class RenameAction extends EditorAction {
3131

@@ -145,42 +145,12 @@ export class RenameAction extends EditorAction {
145145

146146
// start recording of file changes so that we can figure out if a file that
147147
// is to be renamed conflicts with another (concurrent) modification
148-
let sourceModel = this.editor.getModel().getAssociatedResource();
149-
let sourceSelections = this.editor.getSelections();
150-
151-
let supports = RenameRegistry.ordered(this.editor.getModel());
152-
let hasResult = false;
153-
let rejects: string[] = [];
154-
155-
let factory = supports.map(support => {
156-
return () => {
157-
if (!hasResult) {
158-
return support.rename(sourceModel, this.editor.getPosition(), newName).then(result => {
159-
if (!result) {
160-
// ignore
161-
} else if (!result.rejectReason) {
162-
hasResult = true;
163-
return result;
164-
} else {
165-
rejects.push(result.rejectReason);
166-
}
167-
});
168-
}
169-
};
170-
});
171-
172-
let edit = createBulkEdit(this._eventService, this._editorService,
173-
<EditorBrowser.ICodeEditor>this.editor);
148+
let edit = createBulkEdit(this._eventService, this._editorService, <EditorBrowser.ICodeEditor>this.editor);
174149

175-
return sequence(factory).then(values => {
176-
177-
let result = values[0];
178-
if (rejects.length > 0) {
179-
return TPromise.wrapError(rejects.join('\n'));
180-
} else if (!result) {
181-
return TPromise.wrapError(nls.localize('no result', "No result."));
150+
return rename(this.editor.getModel(), this.editor.getPosition(), newName).then(result => {
151+
if (result.rejectReason) {
152+
return TPromise.wrapError(result.rejectReason);
182153
}
183-
184154
edit.add(result.edits);
185155
return edit;
186156
});

src/vs/editor/contrib/rename/common/rename.ts

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,56 @@
55

66
'use strict';
77

8-
import {IRenameSupport} from 'vs/editor/common/modes';
8+
import {IRenameSupport, IRenameResult} from 'vs/editor/common/modes';
9+
import {IModel, IPosition} from 'vs/editor/common/editorCommon';
10+
import {TPromise} from 'vs/base/common/winjs.base';
11+
import {localize} from 'vs/nls';
12+
import {sequence} from 'vs/base/common/async';
13+
import {onUnexpectedError} from 'vs/base/common/errors';
914
import LanguageFeatureRegistry from 'vs/editor/common/modes/languageFeatureRegistry';
1015

1116
export const RenameRegistry = new LanguageFeatureRegistry<IRenameSupport>('renameSupport');
17+
18+
export function rename(model: IModel, position: IPosition, newName: string): TPromise<IRenameResult> {
19+
20+
const supports = RenameRegistry.ordered(model);
21+
const resource = model.getAssociatedResource();
22+
const rejects: string[] = [];
23+
let hasResult = false;
24+
25+
const factory = supports.map(support => {
26+
return () => {
27+
if (!hasResult) {
28+
return support.rename(resource, position, newName).then(result => {
29+
if (!result) {
30+
// ignore
31+
} else if (!result.rejectReason) {
32+
hasResult = true;
33+
return result;
34+
} else {
35+
rejects.push(result.rejectReason);
36+
}
37+
});
38+
}
39+
};
40+
});
41+
42+
return sequence(factory).then(values => {
43+
let result = values[0];
44+
if (rejects.length > 0) {
45+
return <IRenameResult>{
46+
currentName: undefined,
47+
edits: undefined,
48+
rejectReason: rejects.join('\n')
49+
};
50+
} else if (!result) {
51+
return <IRenameResult>{
52+
currentName: undefined,
53+
edits: undefined,
54+
rejectReason: localize('no result', "No result.")
55+
};
56+
} else {
57+
return result;
58+
}
59+
});
60+
}

src/vs/workbench/api/browser/pluginHost.api.impl.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ export class PluginHostAPIImplementation {
283283
return languageFeatures.registerReferenceProvider(selector, provider);
284284
},
285285
registerRenameProvider(selector: vscode.DocumentSelector, provider: vscode.RenameProvider): vscode.Disposable {
286-
return features.rename.register(selector, provider);
286+
return languageFeatures.registerRenameProvider(selector, provider);
287287
},
288288
registerDocumentSymbolProvider(selector: vscode.DocumentSelector, provider: vscode.DocumentSymbolProvider): vscode.Disposable {
289289
return languageFeatures.registerDocumentSymbolProvider(selector, provider);

src/vs/workbench/api/common/extHostLanguageFeatures.ts

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,8 +454,58 @@ class NavigateTypeAdapter implements INavigateTypesSupport {
454454
}
455455
}
456456

457+
class RenameAdapter implements modes.IRenameSupport {
458+
459+
private _documents: PluginHostModelService;
460+
private _provider: vscode.RenameProvider;
461+
462+
constructor(documents: PluginHostModelService, provider: vscode.RenameProvider) {
463+
this._documents = documents;
464+
this._provider = provider;
465+
}
466+
467+
rename(resource: URI, position: IPosition, newName: string): TPromise<modes.IRenameResult> {
468+
469+
let doc = this._documents.getDocument(resource);
470+
let pos = TypeConverters.toPosition(position);
471+
472+
return asWinJsPromise(token => this._provider.provideRenameEdits(doc, pos, newName, token)).then(value => {
473+
474+
if (!value) {
475+
return;
476+
}
477+
478+
let result = <modes.IRenameResult>{
479+
currentName: undefined,
480+
edits: []
481+
};
482+
483+
for (let entry of value.entries()) {
484+
let [uri, textEdits] = entry;
485+
for (let textEdit of textEdits) {
486+
result.edits.push({
487+
resource: <URI>uri,
488+
newText: textEdit.newText,
489+
range: TypeConverters.fromRange(textEdit.range)
490+
});
491+
}
492+
}
493+
return result;
494+
}, err => {
495+
if (typeof err === 'string') {
496+
return <modes.IRenameResult>{
497+
currentName: undefined,
498+
edits: undefined,
499+
rejectReason: err
500+
};
501+
}
502+
return TPromise.wrapError(err);
503+
});
504+
}
505+
}
506+
457507
type Adapter = OutlineAdapter | CodeLensAdapter | DeclarationAdapter | ExtraInfoAdapter | OccurrencesAdapter | ReferenceAdapter | QuickFixAdapter
458-
| DocumentFormattingAdapter | RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter;
508+
| DocumentFormattingAdapter | RangeFormattingAdapter | OnTypeFormattingAdapter | NavigateTypeAdapter | RenameAdapter;
459509

460510
@Remotable.PluginHostContext('ExtHostLanguageFeatures')
461511
export class ExtHostLanguageFeatures {
@@ -638,6 +688,19 @@ export class ExtHostLanguageFeatures {
638688
$getNavigateToItems(handle: number, search: string): TPromise<ITypeBearing[]> {
639689
return this._withAdapter(handle, NavigateTypeAdapter, adapter => adapter.getNavigateToItems(search));
640690
}
691+
692+
// --- rename
693+
694+
registerRenameProvider(selector: vscode.DocumentSelector, provider: vscode.RenameProvider): vscode.Disposable {
695+
const handle = this._nextHandle();
696+
this._adapter[handle] = new RenameAdapter(this._documents, provider);
697+
this._proxy.$registerRenameSupport(handle, selector);
698+
return this._createDisposable(handle);
699+
}
700+
701+
$rename(handle: number, resource: URI, position: IPosition, newName: string): TPromise<modes.IRenameResult> {
702+
return this._withAdapter(handle, RenameAdapter, adapter => adapter.rename(resource, position, newName));
703+
}
641704
}
642705

643706
@Remotable.MainContext('MainThreadLanguageFeatures')
@@ -798,4 +861,15 @@ export class MainThreadLanguageFeatures {
798861
});
799862
return undefined;
800863
}
864+
865+
// --- rename
866+
867+
$registerRenameSupport(handle: number, selector: vscode.DocumentSelector): TPromise<any> {
868+
this._registrations[handle] = RenameRegistry.register(selector, <modes.IRenameSupport>{
869+
rename: (resource: URI, position: IPosition, newName: string): TPromise<modes.IRenameResult> => {
870+
return this._proxy.$rename(handle, resource, position, newName);
871+
}
872+
});
873+
return undefined;
874+
}
801875
}

src/vs/workbench/api/common/languageFeatures.ts

Lines changed: 0 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -131,79 +131,6 @@ export abstract class AbstractExtensionHostFeature<T, P extends AbstractMainThre
131131
}
132132

133133

134-
// -- Rename provider
135-
136-
export class ExtensionHostRename extends AbstractExtensionHostFeature<vscode.RenameProvider, MainThreadRename> {
137-
138-
constructor( @IThreadService threadService: IThreadService) {
139-
super(threadService.getRemotable(MainThreadRename), threadService);
140-
}
141-
142-
_runAsCommand(resource: URI, position: IPosition, newName: string): TPromise<modes.IRenameResult> {
143-
144-
let document = this._models.getDocument(resource);
145-
let pos = TypeConverters.toPosition(position);
146-
147-
let hasResult = false;
148-
let rejects: string[] = [];
149-
let factory = this._getOrderedFor(document).map(provider => {
150-
return () => {
151-
if (!hasResult) {
152-
return asWinJsPromise(token => provider.provideRenameEdits(document, pos, newName, token)).then(result => {
153-
if (result && result.size > 0) {
154-
hasResult = true;
155-
return result;
156-
}
157-
}, err => {
158-
if (typeof err === 'string') {
159-
rejects.push(err);
160-
}
161-
});
162-
}
163-
};
164-
});
165-
166-
return sequence(factory).then(results => {
167-
let rename = results[0];
168-
if (!rename) {
169-
return <modes.IRenameResult>{
170-
rejectReason: rejects.join('\n'),
171-
edits: undefined,
172-
currentName: undefined
173-
};
174-
}
175-
176-
let result = <modes.IRenameResult>{
177-
currentName: undefined,
178-
edits: []
179-
};
180-
for (let entry of rename.entries()) {
181-
let [uri, textEdits] = entry;
182-
for (let textEdit of textEdits) {
183-
result.edits.push({
184-
resource: <URI> uri,
185-
newText: textEdit.newText,
186-
range: TypeConverters.fromRange(textEdit.range)
187-
});
188-
}
189-
}
190-
return result;
191-
});
192-
}
193-
}
194-
195-
@Remotable.MainContext('MainThreadRename')
196-
export class MainThreadRename extends AbstractMainThreadFeature<modes.IRenameSupport> implements modes.IRenameSupport {
197-
198-
constructor( @IThreadService threadService: IThreadService) {
199-
super('vscode.executeDocumentRenameProvider', RenameRegistry, threadService);
200-
}
201-
202-
rename(resource: URI, position: IPosition, newName: string): TPromise<modes.IRenameResult> {
203-
return this._executeCommand(resource, position, newName);
204-
}
205-
}
206-
207134
// --- format
208135

209136
export class ExtHostFormatDocument extends AbstractExtensionHostFeature<vscode.DocumentFormattingEditProvider, MainThreadFormatDocument> {
@@ -628,14 +555,12 @@ export class MainThreadCompletions extends AbstractMainThreadFeature<modes.ISugg
628555
export namespace LanguageFeatures {
629556

630557
export function createMainThreadInstances(threadService: IThreadService): void {
631-
threadService.getRemotable(MainThreadRename);
632558
threadService.getRemotable(MainThreadSignatureHelp);
633559
threadService.getRemotable(MainThreadCompletions);
634560
}
635561

636562
export function createExtensionHostInstances(threadService: IThreadService) {
637563
return {
638-
rename: new ExtensionHostRename(threadService),
639564
signatureHelp: new ExtHostSignatureHelp(threadService),
640565
completions: threadService.getRemotable(ExtHostCompletions)
641566
};

0 commit comments

Comments
 (0)