Skip to content

Commit f483271

Browse files
authored
(feat) basic rename (#172)
* (feat) basic rename #110 * (feat) handle prop rename of component A inside component B * (feat) support for rename of prop of A in A * (fix) linting * (fix) fix range conversion, fix word retrival, tests * (fix) don't rename everything * (feat) add prepareRename support To show a message early that rename is not allowed in certain locations * (fix) use modified mapRangeToOriginal * (fix) don't rename in strings * (fix) don't allow rename of import path We cannot handle it at the moment * (fix) support prop rename without types For that svelte2tsx needs to write out the props as {prop: prop} * (fix) prevent renames in error state * (fix) use ts service for getting variable at position * (fix) convert bind so that source mapping is correct
1 parent 2bb3cdd commit f483271

File tree

27 files changed

+748
-22
lines changed

27 files changed

+748
-22
lines changed

packages/language-server/src/lib/documents/utils.ts

+7
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,10 @@ export function isInTag(position: Position, tagInfo: TagInformation | null): boo
215215
export function getTextInRange(range: Range, text: string) {
216216
return text.substring(offsetAt(range.start, text), offsetAt(range.end, text));
217217
}
218+
219+
export function getLineAtPosition(position: Position, text: string) {
220+
return text.substring(
221+
offsetAt({ line: position.line, character: 0 }, text),
222+
offsetAt({ line: position.line, character: Number.MAX_VALUE }, text),
223+
);
224+
}

packages/language-server/src/plugins/PluginHost.ts

+33
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,39 @@ export class PluginHost implements LSProvider, OnWatchFileChanges {
237237
);
238238
}
239239

240+
async prepareRename(
241+
textDocument: TextDocumentIdentifier,
242+
position: Position,
243+
): Promise<Range | null> {
244+
const document = this.getDocument(textDocument.uri);
245+
if (!document) {
246+
throw new Error('Cannot call methods on an unopened document');
247+
}
248+
249+
return await this.execute<any>(
250+
'prepareRename',
251+
[document, position],
252+
ExecuteMode.FirstNonNull,
253+
);
254+
}
255+
256+
async rename(
257+
textDocument: TextDocumentIdentifier,
258+
position: Position,
259+
newName: string,
260+
): Promise<WorkspaceEdit | null> {
261+
const document = this.getDocument(textDocument.uri);
262+
if (!document) {
263+
throw new Error('Cannot call methods on an unopened document');
264+
}
265+
266+
return await this.execute<any>(
267+
'rename',
268+
[document, position, newName],
269+
ExecuteMode.FirstNonNull,
270+
);
271+
}
272+
240273
onWatchFileChanges(fileName: string, changeType: FileChangeType): void {
241274
for (const support of this.plugins) {
242275
support.onWatchFileChanges?.(fileName, changeType);

packages/language-server/src/plugins/interfaces.ts

+11-1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,15 @@ export interface UpdateImportsProvider {
9595
updateImports(fileRename: FileRename): Resolvable<WorkspaceEdit | null>;
9696
}
9797

98+
export interface RenameProvider {
99+
rename(
100+
document: Document,
101+
position: Position,
102+
newName: string,
103+
): Resolvable<WorkspaceEdit | null>;
104+
prepareRename(document: Document, position: Position): Resolvable<Range | null>;
105+
}
106+
98107
export interface OnWatchFileChanges {
99108
onWatchFileChanges(fileName: string, changeType: FileChangeType): void;
100109
}
@@ -109,6 +118,7 @@ export type LSProvider = DiagnosticsProvider &
109118
DocumentSymbolsProvider &
110119
DefinitionsProvider &
111120
UpdateImportsProvider &
112-
CodeActionsProvider;
121+
CodeActionsProvider &
122+
RenameProvider;
113123

114124
export type Plugin = Partial<LSProvider & OnWatchFileChanges>;

packages/language-server/src/plugins/typescript/TypeScriptPlugin.ts

+25
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {
3232
FileRename,
3333
HoverProvider,
3434
OnWatchFileChanges,
35+
RenameProvider,
3536
UpdateImportsProvider,
3637
} from '../interfaces';
3738
import { SnapshotFragment } from './DocumentSnapshot';
@@ -49,6 +50,7 @@ import {
4950
getScriptKindFromFileName,
5051
symbolKindFromString,
5152
} from './utils';
53+
import { RenameProviderImpl } from './features/RenameProvider';
5254

5355
export class TypeScriptPlugin
5456
implements
@@ -58,6 +60,7 @@ export class TypeScriptPlugin
5860
DefinitionsProvider,
5961
CodeActionsProvider,
6062
UpdateImportsProvider,
63+
RenameProvider,
6164
OnWatchFileChanges,
6265
CompletionsProvider<CompletionEntryWithIdentifer> {
6366
private readonly configManager: LSConfigManager;
@@ -66,6 +69,7 @@ export class TypeScriptPlugin
6669
private readonly codeActionsProvider: CodeActionsProviderImpl;
6770
private readonly updateImportsProvider: UpdateImportsProviderImpl;
6871
private readonly diagnosticsProvider: DiagnosticsProviderImpl;
72+
private readonly renameProvider: RenameProviderImpl;
6973

7074
constructor(
7175
docManager: DocumentManager,
@@ -78,6 +82,7 @@ export class TypeScriptPlugin
7882
this.codeActionsProvider = new CodeActionsProviderImpl(this.lsAndTsDocResolver);
7983
this.updateImportsProvider = new UpdateImportsProviderImpl(this.lsAndTsDocResolver);
8084
this.diagnosticsProvider = new DiagnosticsProviderImpl(this.lsAndTsDocResolver);
85+
this.renameProvider = new RenameProviderImpl(this.lsAndTsDocResolver);
8186
}
8287

8388
async getDiagnostics(document: Document): Promise<Diagnostic[]> {
@@ -227,6 +232,26 @@ export class TypeScriptPlugin
227232
);
228233
}
229234

235+
async prepareRename(document: Document, position: Position): Promise<Range | null> {
236+
if (!this.featureEnabled('rename')) {
237+
return null;
238+
}
239+
240+
return this.renameProvider.prepareRename(document, position);
241+
}
242+
243+
async rename(
244+
document: Document,
245+
position: Position,
246+
newName: string,
247+
): Promise<WorkspaceEdit | null> {
248+
if (!this.featureEnabled('rename')) {
249+
return null;
250+
}
251+
252+
return this.renameProvider.rename(document, position, newName);
253+
}
254+
230255
async getCodeActions(
231256
document: Document,
232257
range: Range,

0 commit comments

Comments
 (0)