提交 addd44d6 编写于 作者: J Johannes Rieken

simplified resolve rename location proposal, #7340

上级 406b33ab
......@@ -924,15 +924,9 @@ export interface WorkspaceEdit {
rejectReason?: string; // TODO@joh, move to rename
}
export interface RenameContext {
range: IRange;
text: string;
message?: string;
}
export interface RenameProvider {
provideRenameEdits(model: model.ITextModel, position: Position, newName: string, token: CancellationToken): WorkspaceEdit | Thenable<WorkspaceEdit>;
resolveRenameLocation?(model: model.ITextModel, position: Position, token: CancellationToken): RenameContext | Thenable<RenameContext>;
resolveRenameLocation?(model: model.ITextModel, position: Position, token: CancellationToken): IRange | Thenable<IRange>;
}
......
......@@ -23,10 +23,10 @@ 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, RenameContext, RenameProvider } from 'vs/editor/common/modes';
import { WorkspaceEdit, RenameProviderRegistry, RenameProvider } from 'vs/editor/common/modes';
import { Position } from 'vs/editor/common/core/position';
import { alert } from 'vs/base/browser/ui/aria/aria';
import { Range } from 'vs/editor/common/core/range';
import { Range, IRange } from 'vs/editor/common/core/range';
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';
......@@ -47,26 +47,23 @@ class RenameSkeleton {
return this._provider.length > 0;
}
async resolveRenameInformation(): TPromise<RenameContext> {
async resolveRenameLocation(): TPromise<IRange> {
let [provider] = this._provider;
let information: RenameContext;
let range: IRange;
if (provider.resolveRenameLocation) {
information = await asWinJsPromise(token => provider.resolveRenameLocation(this.model, this.position, token));
range = await asWinJsPromise(token => provider.resolveRenameLocation(this.model, this.position, token));
}
if (!information) {
if (!range) {
let word = this.model.getWordAtPosition(this.position);
if (word) {
information = {
range: new Range(this.position.lineNumber, word.startColumn, this.position.lineNumber, word.endColumn),
text: word.word
};
range = new Range(this.position.lineNumber, word.startColumn, this.position.lineNumber, word.endColumn);
}
}
return information;
return range;
}
async provideRenameEdits(newName: string, i: number = 0, rejects: string[] = []): TPromise<WorkspaceEdit> {
......@@ -134,27 +131,26 @@ class RenameController implements IEditorContribution {
const position = this.editor.getPosition();
const skeleton = new RenameSkeleton(this.editor.getModel(), position);
let context = await skeleton.resolveRenameInformation();
if (!context) {
return undefined;
}
if (context.message) {
MessageController.get(this.editor).showMessage(context.message, position);
let range: IRange;
try {
range = await skeleton.resolveRenameLocation();
} catch (e) {
MessageController.get(this.editor).showMessage(e, position);
return undefined;
}
let text = this.editor.getModel().getValueInRange(range);
let selection = this.editor.getSelection();
let selectionStart = 0;
let selectionEnd = context.text.length;
let selectionEnd = text.length;
if (!selection.isEmpty() && selection.startLineNumber === selection.endLineNumber) {
selectionStart = Math.max(0, selection.startColumn - context.range.startColumn);
selectionEnd = Math.min(context.range.endColumn, selection.endColumn) - context.range.startColumn;
selectionStart = Math.max(0, selection.startColumn - range.startColumn);
selectionEnd = Math.min(range.endColumn, selection.endColumn) - range.startColumn;
}
this._renameInputVisible.set(true);
return this._renameInputField.getInput(Range.lift(context.range), context.text, selectionStart, selectionEnd).then(newNameOrFocusFlag => {
return this._renameInputField.getInput(Range.lift(range), text, selectionStart, selectionEnd).then(newNameOrFocusFlag => {
this._renameInputVisible.reset();
if (typeof newNameOrFocusFlag === 'boolean') {
......@@ -185,7 +181,7 @@ class RenameController implements IEditorContribution {
this.editor.setSelection(selection);
}
// alert
alert(nls.localize('aria', "Successfully renamed '{0}' to '{1}'. Summary: {2}", context.text, newNameOrFocusFlag, edit.ariaMessage()));
alert(nls.localize('aria', "Successfully renamed '{0}' to '{1}'. Summary: {2}", text, newNameOrFocusFlag, edit.ariaMessage()));
});
}, err => {
......
......@@ -4986,15 +4986,9 @@ declare namespace monaco.languages {
rejectReason?: string;
}
export interface RenameContext {
range: IRange;
text: string;
message?: string;
}
export interface RenameProvider {
provideRenameEdits(model: editor.ITextModel, position: Position, newName: string, token: CancellationToken): WorkspaceEdit | Thenable<WorkspaceEdit>;
resolveRenameLocation?(model: editor.ITextModel, position: Position, token: CancellationToken): RenameContext | Thenable<RenameContext>;
resolveRenameLocation?(model: editor.ITextModel, position: Position, token: CancellationToken): IRange | Thenable<IRange>;
}
export interface Command {
......
......@@ -439,12 +439,6 @@ declare module 'vscode' {
//#region Joh: rename context
export interface RenameContext {
range?: Range;
newName?: string;
message?: string;
}
export interface RenameProvider2 extends RenameProvider {
/**
......@@ -454,9 +448,9 @@ declare module 'vscode' {
* @param document The document in which rename will be invoked.
* @param position The position at which rename will be invoked.
* @param token A cancellation token.
* @return A `RenameContext` with more information. The lack of a result can signaled by returning `undefined` or `null`.
* @return The range of the identifier that is to be renamed. The lack of a result can signaled by returning `undefined` or `null`.
*/
resolveRenameLocation?(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<RenameContext>;
resolveRenameLocation?(document: TextDocument, position: Position, token: CancellationToken): ProviderResult<Range>;
}
......
......@@ -13,7 +13,7 @@ import { WorkspaceSymbolProviderRegistry, IWorkspaceSymbolProvider } from 'vs/wo
import { wireCancellationToken } from 'vs/base/common/async';
import { CancellationToken } from 'vs/base/common/cancellation';
import { Position as EditorPosition } from 'vs/editor/common/core/position';
import { Range as EditorRange } from 'vs/editor/common/core/range';
import { Range as EditorRange, IRange } from 'vs/editor/common/core/range';
import { ExtHostContext, MainThreadLanguageFeaturesShape, ExtHostLanguageFeaturesShape, MainContext, IExtHostContext, ISerializedLanguageConfiguration, ISerializedRegExp, ISerializedIndentationRule, ISerializedOnEnterRule, LocationDto, SymbolInformationDto, CodeActionDto, reviveWorkspaceEditDto, ISerializedDocumentFilter } from '../node/extHost.protocol';
import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry';
import { LanguageConfiguration, IndentationRule, OnEnterRule } from 'vs/editor/common/modes/languageConfiguration';
......@@ -257,7 +257,7 @@ export class MainThreadLanguageFeatures implements MainThreadLanguageFeaturesSha
return wireCancellationToken(token, this._proxy.$provideRenameEdits(handle, model.uri, position, newName)).then(reviveWorkspaceEditDto);
},
resolveRenameLocation: supportResolveLocation
? (model: ITextModel, position: EditorPosition, token: CancellationToken): Thenable<modes.RenameContext> => wireCancellationToken(token, this._proxy.$resolveRenameLocation(handle, model.uri, position))
? (model: ITextModel, position: EditorPosition, token: CancellationToken): Thenable<IRange> => wireCancellationToken(token, this._proxy.$resolveRenameLocation(handle, model.uri, position))
: undefined
});
}
......
......@@ -700,7 +700,7 @@ export interface ExtHostLanguageFeaturesShape {
$resolveWorkspaceSymbol(handle: number, symbol: SymbolInformationDto): TPromise<SymbolInformationDto>;
$releaseWorkspaceSymbols(handle: number, id: number): void;
$provideRenameEdits(handle: number, resource: UriComponents, position: IPosition, newName: string): TPromise<WorkspaceEditDto>;
$resolveRenameLocation(handle: number, resource: UriComponents, position: IPosition): TPromise<modes.RenameContext>;
$resolveRenameLocation(handle: number, resource: UriComponents, position: IPosition): TPromise<IRange>;
$provideCompletionItems(handle: number, resource: UriComponents, position: IPosition, context: modes.SuggestContext): TPromise<SuggestResultDto>;
$resolveCompletionItem(handle: number, resource: UriComponents, position: IPosition, suggestion: modes.ISuggestion): TPromise<modes.ISuggestion>;
$releaseCompletionItems(handle: number, id: number): void;
......
......@@ -506,7 +506,7 @@ class RenameAdapter {
});
}
resolveRenameLocation(resource: URI, position: IPosition): TPromise<modes.RenameContext> {
resolveRenameLocation(resource: URI, position: IPosition): TPromise<IRange> {
if (typeof this._provider.resolveRenameLocation !== 'function') {
return TPromise.as(undefined);
}
......@@ -514,23 +514,19 @@ class RenameAdapter {
let doc = this._documents.getDocumentData(resource).document;
let pos = TypeConverters.toPosition(position);
return asWinJsPromise(token => this._provider.resolveRenameLocation(doc, pos, token)).then(context => {
if (!context) {
return asWinJsPromise(token => this._provider.resolveRenameLocation(doc, pos, token)).then(range => {
if (!range) {
return undefined;
}
if (context.range && (!context.range.isSingleLine || context.range.start.line !== pos.line)) {
if (range && (!range.isSingleLine || range.start.line !== pos.line)) {
console.warn('INVALID rename context, range must be single line and on the same line');
return undefined;
}
return <modes.RenameContext>{
range: TypeConverters.fromRange(context.range),
text: context.newName || doc.getText(context.range)
};
return TypeConverters.fromRange(range);
});
}
}
class SuggestAdapter {
static supportsResolving(provider: vscode.CompletionItemProvider): boolean {
......@@ -1092,7 +1088,7 @@ export class ExtHostLanguageFeatures implements ExtHostLanguageFeaturesShape {
return this._withAdapter(handle, RenameAdapter, adapter => adapter.provideRenameEdits(URI.revive(resource), position, newName));
}
$resolveRenameLocation(handle: number, resource: URI, position: IPosition): TPromise<modes.RenameContext> {
$resolveRenameLocation(handle: number, resource: URI, position: IPosition): TPromise<IRange> {
return this._withAdapter(handle, RenameAdapter, adapter => adapter.resolveRenameLocation(resource, position));
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册