Skip to content

Commit 8338336

Browse files
authored
Merge pull request #187 from zardoy/develop
2 parents 52cb94f + d18c985 commit 8338336

File tree

10 files changed

+96
-7
lines changed

10 files changed

+96
-7
lines changed

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@
7070
{
7171
"command": "printPerformanceMemoryInfo",
7272
"title": "Print Performance & Memory Info"
73+
},
74+
{
75+
"command": "migrateRequireToImports",
76+
"title": "Migrate Require to Imports"
7377
}
7478
],
7579
"keybindings": [

src/configurationType.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,12 @@ export type Configuration = {
582582
* @default false
583583
*/
584584
'experiments.enableInsertNameOfSuggestionFix': boolean
585+
/**
586+
* Speed up JSX linked editing by not using actual tsserver command when possible, which in theory may introduce some inconsistencies.
587+
* Note that currently it doesn't really help if you have `"typescript.tsserver.useSyntaxServer": "auto"` in the settings.
588+
* @default true
589+
*/
590+
'experiments.speedLinkedEditing': boolean
585591
/**
586592
* Map *symbol - array of modules* to change sorting of imports - first available takes precedence in auto import code fixes (+ import all action)
587593
*

src/specialCommands.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { compact } from '@zardoy/utils'
77
import { offsetPosition } from '@zardoy/vscode-utils/build/position'
88
import { RequestInputTypes, RequestOutputTypes } from '../typescript/src/ipcTypes'
99
import { sendCommand } from './sendCommand'
10-
import { tsRangeToVscode, tsRangeToVscodeSelection } from './util'
10+
import { tsRangeToVscode, tsRangeToVscodeSelection, tsTextChangesToVscodeTextEdits } from './util'
1111
import { onCompletionAcceptedOverride } from './onCompletionAccepted'
1212

1313
export default () => {
@@ -309,6 +309,16 @@ export default () => {
309309
console.show(true)
310310
})
311311

312+
registerExtensionCommand('migrateRequireToImports', async () => {
313+
const data = await sendCommand('getMigrateToImportsEdits', {})
314+
if (!data) return
315+
const { document } = vscode.window.activeTextEditor!
316+
const edits = tsTextChangesToVscodeTextEdits(document, data)
317+
const edit = new vscode.WorkspaceEdit()
318+
edit.set(document.uri, edits)
319+
await vscode.workspace.applyEdit(edit)
320+
})
321+
312322
// registerExtensionCommand('insertImportFlatten', () => {
313323
// // got -> default, got
314324
// type A = ts.Type

src/vueVolarSupport.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,23 @@ export default () => {
7272
const isConfigValueChanged = (settingId: string) => {
7373
if (process.env.PLATFORM !== 'web') {
7474
const config = vscode.workspace.getConfiguration('')
75-
const userValue = config.get<string>(settingId)
76-
if (userValue === config.inspect(settingId)!.defaultValue) return false
75+
let userValue = config.get<string>(settingId)
76+
if (!userValue || userValue === config.inspect(settingId)!.defaultValue) return false
7777
// means that value was set by us programmatically, let's update it
7878
// eslint-disable-next-line @typescript-eslint/no-require-imports
79-
if (userValue?.startsWith(require('path').join(extensionCtx.extensionPath, '../..'))) return false
79+
let extensionsBasePath = require('path').join(extensionCtx.extensionPath, '../..') as string
80+
const normalizePathWin = (path: string) => {
81+
// normalize casing of drive
82+
if (/^[a-z]:/.test(path)) {
83+
path = path[0]!.toUpperCase() + path.slice(1)
84+
}
85+
86+
return path.replace(/\\/g, '/')
87+
}
88+
89+
userValue = normalizePathWin(userValue)
90+
extensionsBasePath = normalizePathWin(extensionsBasePath)
91+
if (userValue.startsWith(extensionsBasePath)) return false
8092
return true
8193
}
8294

typescript/src/completions/filterJsxComponents.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export default (entries: ts.CompletionEntry[], node: ts.Node, position: number,
7676
let shouldBeCached = firstDeclarationFileName.includes('node_modules')
7777
if (!shouldBeCached && firstDeclaration.getSourceFile().fileName === fileName) {
7878
// startMark()
79-
const definitionAtPosition = languageService.getDefinitionAtPosition(fileName, firstDeclaration.pos + 1)?.[0]
79+
const definitionAtPosition = languageService.getDefinitionAtPosition(fileName, firstDeclaration.pos + firstDeclaration.getLeadingTriviaWidth())?.[0]
8080
// addMark('getDefinitionAtPosition')
8181
if (!definitionAtPosition) return
8282
shouldBeCached = definitionAtPosition.fileName.includes('node_modules')

typescript/src/decorateEditsForFileRename.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,21 @@ export default (proxy: ts.LanguageService, languageService: ts.LanguageService,
77
proxy.getEditsForFileRename = (oldFilePath, newFilePath, formatOptions, preferences) => {
88
let edits = languageService.getEditsForFileRename(oldFilePath, newFilePath, formatOptions, preferences)
99
if (c('renameImportNameOfFileRename')) {
10-
const predictedNameFromPath = (p: string) => camelCase(p.split(/[/\\]/g).pop()!.replace(/\..+/, ''))
10+
const predictedNameFromPath = (p: string) => {
11+
const input = p.split(/[/\\]/g).pop()!.replace(/\..+/, '')
12+
const transformed = camelCase(input)
13+
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
14+
const isFirstUppercase = input && input.startsWith(input[0]!.toUpperCase())
15+
return isFirstUppercase ? transformed[0]!.toUpperCase() + transformed.slice(1) : transformed
16+
}
1117
const oldPredictedName = predictedNameFromPath(oldFilePath)
1218
const newPredictedName = predictedNameFromPath(newFilePath)
1319
for (const edit of edits) {
1420
const possiblyAddRename = (identifier: ts.Identifier | undefined) => {
1521
if (identifier?.text !== oldPredictedName) return
1622
const sourceFile = languageService.getProgram()!.getSourceFile(edit.fileName)!
17-
const newRenameEdits = proxy.findRenameLocations(edit.fileName, identifier.pos, false, false, preferences ?? {}) ?? []
23+
const newRenameEdits =
24+
proxy.findRenameLocations(edit.fileName, identifier.pos + identifier.getLeadingTriviaWidth(), false, false, preferences ?? {}) ?? []
1825
if (!newRenameEdits) return
1926
// maybe cancel symbol rename on collision instead?
2027
const newInsertName = tsFull.getUniqueName(newPredictedName, sourceFile as any)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { GetConfig } from './types'
2+
3+
export default (proxy: ts.LanguageService, languageService: ts.LanguageService, languageServiceHost: ts.LanguageServiceHost, c: GetConfig) => {
4+
// patch JSX tag linked editing to improve performance (needed for great user experience)
5+
6+
let lastLinkedEditingRangeRequest:
7+
| {
8+
pos: number
9+
fileName: string
10+
result: ts.LinkedEditingInfo
11+
}
12+
| undefined
13+
proxy.getLinkedEditingRangeAtPosition = (fileName, position) => {
14+
if (
15+
c('experiments.speedLinkedEditing') &&
16+
lastLinkedEditingRangeRequest &&
17+
lastLinkedEditingRangeRequest.pos === position - 1 &&
18+
lastLinkedEditingRangeRequest.fileName === fileName
19+
) {
20+
lastLinkedEditingRangeRequest.pos = position
21+
lastLinkedEditingRangeRequest.result.ranges[0]!.length++
22+
lastLinkedEditingRangeRequest.result.ranges[1]!.start++
23+
lastLinkedEditingRangeRequest.result.ranges[1]!.length++
24+
return lastLinkedEditingRangeRequest.result
25+
}
26+
lastLinkedEditingRangeRequest = undefined
27+
28+
const prior = languageService.getLinkedEditingRangeAtPosition(fileName, position)
29+
if (!prior) return
30+
lastLinkedEditingRangeRequest = {
31+
pos: position,
32+
fileName,
33+
result: globalThis.structuredClone(prior),
34+
}
35+
return prior
36+
}
37+
}

typescript/src/decorateProxy.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import decorateSignatureHelp from './decorateSignatureHelp'
1919
import decorateFindRenameLocations from './decorateFindRenameLocations'
2020
import decorateQuickInfoAtPosition from './decorateQuickInfoAtPosition'
2121
import decorateEditsForFileRename from './decorateEditsForFileRename'
22+
import decorateLinkedEditing from './decorateLinkedEditing'
2223

2324
/** @internal */
2425
export const thisPluginMarker = '__essentialPluginsMarker__'
@@ -102,6 +103,7 @@ export const decorateLanguageService = (
102103
decorateSignatureHelp(proxy, languageService, languageServiceHost, c)
103104
decorateFindRenameLocations(proxy, languageService, c)
104105
decorateQuickInfoAtPosition(proxy, languageService, languageServiceHost, c)
106+
decorateLinkedEditing(proxy, languageService, languageServiceHost, c)
105107

106108
libDomPatching(languageServiceHost, c)
107109

typescript/src/ipcTypes.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const triggerCharacterCommands = [
1717
'getLastResolvedCompletion',
1818
'getArgumentReferencesFromCurrentParameter',
1919
'performanceInfo',
20+
'getMigrateToImportsEdits',
2021
] as const
2122

2223
export type TriggerCharacterCommand = (typeof triggerCharacterCommands)[number]
@@ -115,6 +116,7 @@ export type RequestOutputTypes = {
115116
}
116117
getArgumentReferencesFromCurrentParameter: Array<{ line: number; character: number; filename: string }>
117118
'emmet-completions': EmmetResult
119+
getMigrateToImportsEdits: ts.TextChange[]
118120
}
119121

120122
// export type EmmetResult = {

typescript/src/specialCommands/handle.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,15 @@ export default (
304304
memoryUsedMb: toMb(process.memoryUsage().heapUsed),
305305
}
306306
}
307+
if (specialCommand === 'getMigrateToImportsEdits') {
308+
const combinedCodeFix = languageService.getCombinedCodeFix(
309+
{ type: 'file', fileName: sourceFile.fileName },
310+
'requireInTs',
311+
ts.getDefaultFormatCodeSettings(),
312+
preferences,
313+
)
314+
return combinedCodeFix.changes[0]?.textChanges
315+
}
307316

308317
return null
309318
}

0 commit comments

Comments
 (0)