1
1
import lodashGet from 'lodash.get'
2
+ import { camelCase } from 'change-case'
3
+ import _ from 'lodash'
2
4
import { getCompletionsAtPosition , PrevCompletionMap , PrevCompletionsAdditionalData } from './completionsAtPosition'
3
5
import { RequestOptionsTypes , TriggerCharacterCommand } from './ipcTypes'
4
6
import { getNavTreeItems } from './getPatchedNavTree'
@@ -15,6 +17,7 @@ import decorateWorkspaceSymbolSearch from './workspaceSymbolSearch'
15
17
import decorateFormatFeatures from './decorateFormatFeatures'
16
18
import libDomPatching from './libDomPatching'
17
19
import decorateSignatureHelp from './decorateSignatureHelp'
20
+ import { approveCast , findChildContainingExactPosition } from './utils'
18
21
19
22
/** @internal */
20
23
export const thisPluginMarker = '__essentialPluginsMarker__'
@@ -46,6 +49,49 @@ export const decorateLanguageService = (
46
49
let prevCompletionsMap : PrevCompletionMap
47
50
let prevCompletionsAdittionalData : PrevCompletionsAdditionalData
48
51
52
+ proxy . getEditsForFileRename = ( oldFilePath , newFilePath , formatOptions , preferences ) => {
53
+ let edits = languageService . getEditsForFileRename ( oldFilePath , newFilePath , formatOptions , preferences )
54
+ if ( c ( 'renameImportNameOfFileRename' ) ) {
55
+ const predictedNameFromPath = ( p : string ) => camelCase ( p . split ( / [ / \\ ] / g) . pop ( ) ! . replace ( / \. .+ / , '' ) )
56
+ const oldPredictedName = predictedNameFromPath ( oldFilePath )
57
+ const newPredictedName = predictedNameFromPath ( newFilePath )
58
+ for ( const edit of edits ) {
59
+ const possiblyAddRename = ( identifier : ts . Identifier | undefined ) => {
60
+ if ( identifier ?. text !== oldPredictedName ) return
61
+ const sourceFile = languageService . getProgram ( ) ! . getSourceFile ( edit . fileName ) !
62
+ const newRenameEdits = proxy . findRenameLocations ( edit . fileName , identifier . pos , false , false ) ?? [ ]
63
+ if ( ! newRenameEdits ) return
64
+ // maybe cancel symbol rename on collision instead?
65
+ const newInsertName = tsFull . getUniqueName ( newPredictedName , sourceFile as any )
66
+ const addEdits = Object . entries ( _ . groupBy ( newRenameEdits , ( { fileName } ) => fileName ) ) . map (
67
+ ( [ fileName , changes ] ) : ts . FileTextChanges => ( {
68
+ fileName,
69
+ textChanges : changes . map (
70
+ ( { prefixText = '' , suffixText = '' , textSpan } ) : ts . TextChange => ( {
71
+ newText : prefixText + newInsertName + suffixText ,
72
+ span : textSpan ,
73
+ } ) ,
74
+ ) ,
75
+ } ) ,
76
+ )
77
+ edits = [ ...edits , ...addEdits ]
78
+ }
79
+ for ( const textChange of edit . textChanges ) {
80
+ const node = findChildContainingExactPosition ( languageService . getProgram ( ) ! . getSourceFile ( edit . fileName ) ! , textChange . span . start )
81
+ if ( ! node ) continue
82
+ if ( node && ts . isStringLiteral ( node ) && ts . isImportDeclaration ( node . parent ) && node . parent . importClause ) {
83
+ const { importClause } = node . parent
84
+ possiblyAddRename ( importClause ?. name )
85
+ if ( approveCast ( importClause . namedBindings , ts . isNamespaceImport ) ) {
86
+ possiblyAddRename ( importClause . namedBindings . name )
87
+ }
88
+ }
89
+ }
90
+ }
91
+ }
92
+ return edits
93
+ }
94
+
49
95
proxy . getCompletionsAtPosition = ( fileName , position , options , formatOptions ) => {
50
96
if ( options ?. triggerCharacter && typeof options . triggerCharacter !== 'string' ) {
51
97
return languageService . getCompletionsAtPosition ( fileName , position , options )
0 commit comments