Skip to content

Commit 5cf98aa

Browse files
committed
refactor: special commands input & output auto infer; also renames types!
1 parent bde2173 commit 5cf98aa

File tree

10 files changed

+93
-97
lines changed

10 files changed

+93
-97
lines changed

src/codeActionProvider.ts

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as vscode from 'vscode'
22
import { defaultJsSupersetLangsWithVue } from '@zardoy/vscode-utils/build/langs'
33
import { registerExtensionCommand, showQuickPick, getExtensionSetting, getExtensionCommandId } from 'vscode-framework'
44
import { compact } from '@zardoy/utils'
5-
import { RequestResponseTypes, RequestOptionsTypes } from '../typescript/src/ipcTypes'
5+
import { RequestOutputTypes, RequestInputTypes } from '../typescript/src/ipcTypes'
66
import { sendCommand } from './sendCommand'
77
import { tsTextChangesToVscodeTextEdits, vscodeRangeToTs, tsTextChangesToVscodeSnippetTextEdits } from './util'
88

@@ -26,7 +26,7 @@ export default () => {
2626
return
2727
}
2828

29-
const fixAllEdits = await sendCommand<RequestResponseTypes['getFixAllEdits']>('getFixAllEdits', {
29+
const fixAllEdits = await sendCommand('getFixAllEdits', {
3030
document,
3131
})
3232
if (!fixAllEdits || token.isCancellationRequested) return
@@ -89,16 +89,13 @@ export default () => {
8989
async resolveCodeAction(codeAction: ExtendedCodeAction, token) {
9090
const { document } = codeAction
9191
if (!document) throw new Error('Unresolved code action without document')
92-
const result = await sendCommand<RequestResponseTypes['getExtendedCodeActionEdits'], RequestOptionsTypes['getExtendedCodeActionEdits']>(
93-
'getExtendedCodeActionEdits',
94-
{
95-
document,
96-
inputOptions: {
97-
applyCodeActionTitle: codeAction.title,
98-
range: vscodeRangeToTs(document, codeAction.diagnostics?.length ? codeAction.diagnostics[0]!.range : codeAction.requestRange),
99-
},
92+
const result = await sendCommand('getExtendedCodeActionEdits', {
93+
document,
94+
inputOptions: {
95+
applyCodeActionTitle: codeAction.title,
96+
range: vscodeRangeToTs(document, codeAction.diagnostics?.length ? codeAction.diagnostics[0]!.range : codeAction.requestRange),
10097
},
101-
)
98+
})
10299
if (!result) throw new Error('No code action edits. Try debug.')
103100
const { edits = [], snippetEdits = [] } = result
104101
const workspaceEdit = new vscode.WorkspaceEdit()
@@ -111,9 +108,9 @@ export default () => {
111108
},
112109
})
113110

114-
registerExtensionCommand('applyRefactor' as any, async (_, arg?: RequestResponseTypes['getTwoStepCodeActions']) => {
111+
registerExtensionCommand('applyRefactor' as any, async (_, arg?: RequestOutputTypes['getTwoStepCodeActions']) => {
115112
if (!arg) return
116-
let sendNextData: RequestOptionsTypes['twoStepCodeActionSecondStep']['data'] | undefined
113+
let sendNextData: RequestInputTypes['twoStepCodeActionSecondStep']['data'] | undefined
117114
const { turnArrayIntoObject } = arg
118115
if (turnArrayIntoObject) {
119116
const { keysCount, totalCount, totalObjectCount } = turnArrayIntoObject
@@ -151,7 +148,7 @@ export default () => {
151148
})
152149

153150
async function getPossibleTwoStepRefactorings(range: vscode.Range, document = vscode.window.activeTextEditor!.document) {
154-
return sendCommand<RequestResponseTypes['getTwoStepCodeActions'], RequestOptionsTypes['getTwoStepCodeActions']>('getTwoStepCodeActions', {
151+
return sendCommand('getTwoStepCodeActions', {
155152
document,
156153
position: range.start,
157154
inputOptions: {
@@ -161,16 +158,13 @@ export default () => {
161158
}
162159

163160
async function getSecondStepRefactoringData(range: vscode.Range, secondStepData?: any, document = vscode.window.activeTextEditor!.document) {
164-
return sendCommand<RequestResponseTypes['twoStepCodeActionSecondStep'], RequestOptionsTypes['twoStepCodeActionSecondStep']>(
165-
'twoStepCodeActionSecondStep',
166-
{
167-
document,
168-
position: range.start,
169-
inputOptions: {
170-
range: vscodeRangeToTs(document, range),
171-
data: secondStepData,
172-
},
161+
return sendCommand('twoStepCodeActionSecondStep', {
162+
document,
163+
position: range.start,
164+
inputOptions: {
165+
range: vscodeRangeToTs(document, range),
166+
data: secondStepData,
173167
},
174-
)
168+
})
175169
}
176170
}

src/emmet.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import * as vscode from 'vscode'
22
import { compact } from '@zardoy/utils'
33
import { getExtensionSetting, registerExtensionCommand } from 'vscode-framework'
4-
import { EmmetResult } from '../typescript/src/ipcTypes'
54
import { sendCommand } from './sendCommand'
65
import { Configuration } from './configurationType'
76

@@ -29,7 +28,7 @@ export const registerEmmet = async () => {
2928
const cursorOffset: number = document.offsetAt(position)
3029

3130
if (context.triggerKind !== vscode.CompletionTriggerKind.TriggerForIncompleteCompletions || !lastStartOffset) {
32-
const result = await sendCommand<EmmetResult>('emmet-completions', { document, position })
31+
const result = await sendCommand('emmet-completions', { document, position })
3332
if (!result) {
3433
lastStartOffset = undefined
3534
return

src/sendCommand.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
11
import * as vscode from 'vscode'
22
import { getActiveRegularEditor } from '@zardoy/vscode-utils'
33
import { getExtensionSetting } from 'vscode-framework'
4-
import { passthroughExposedApiCommands, TriggerCharacterCommand } from '../typescript/src/ipcTypes'
4+
import { passthroughExposedApiCommands, TriggerCharacterCommand, RequestInputTypes, RequestOutputTypes } from '../typescript/src/ipcTypes'
55

6-
type SendCommandData<K> = {
6+
type SendCommandData<Input> = {
77
position?: vscode.Position
88
document?: vscode.TextDocument
9-
inputOptions?: K
10-
}
11-
export const sendCommand = async <Response, K = any>(
12-
command: TriggerCharacterCommand,
13-
sendCommandDataArg?: SendCommandData<K>,
14-
): Promise<Response | undefined> => {
9+
// eslint-disable-next-line @typescript-eslint/ban-types
10+
} & ([Input] extends [never] ? {} : { inputOptions: Input })
11+
12+
export const sendCommand = async <
13+
Command extends TriggerCharacterCommand,
14+
Input = RequestInputTypes[Command & keyof RequestInputTypes],
15+
Output = RequestOutputTypes[Command & keyof RequestOutputTypes] extends never ? any : RequestOutputTypes[Command & keyof RequestOutputTypes],
16+
>(
17+
command: Command,
18+
sendCommandDataArg: SendCommandData<Input>,
19+
): Promise<Output | undefined> => {
1520
// plugin id disabled, languageService would not understand the special trigger character
1621
if (!getExtensionSetting('enablePlugin')) {
1722
console.warn('Ignoring request because plugin is disabled')
@@ -31,10 +36,10 @@ export const sendCommand = async <Response, K = any>(
3136
}
3237

3338
const _editor = getActiveRegularEditor()!
34-
const { document: { uri } = _editor.document, position = _editor.selection.active, inputOptions } = sendCommandDataArg ?? {}
39+
const { document: { uri } = _editor.document, position = _editor.selection.active } = sendCommandDataArg ?? {}
3540

36-
if (inputOptions) {
37-
command = `${command}?${JSON.stringify(inputOptions)}` as any
41+
if ('inputOptions' in sendCommandDataArg) {
42+
command = `${command}?${JSON.stringify(sendCommandDataArg.inputOptions)}` as any
3843
}
3944

4045
if (process.env.NODE_ENV === 'development') console.time(`request ${command}`)

src/specialCommands.ts

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { showQuickPick } from '@zardoy/vscode-utils/build/quickPick'
55
import _ from 'lodash'
66
import { compact } from '@zardoy/utils'
77
import { offsetPosition } from '@zardoy/vscode-utils/build/position'
8-
import { RequestOptionsTypes, RequestResponseTypes } from '../typescript/src/ipcTypes'
8+
import { RequestInputTypes, RequestOutputTypes } from '../typescript/src/ipcTypes'
99
import { sendCommand } from './sendCommand'
1010
import { tsRangeToVscode, tsRangeToVscodeSelection } from './util'
1111
import { onCompletionAcceptedOverride } from './onCompletionAccepted'
@@ -15,10 +15,7 @@ export default () => {
1515
const editor = getActiveRegularEditor()
1616
if (!editor) return
1717
const { selection, document } = editor
18-
const response = await sendCommand<
19-
RequestResponseTypes['removeFunctionArgumentsTypesInSelection'],
20-
RequestOptionsTypes['removeFunctionArgumentsTypesInSelection']
21-
>('removeFunctionArgumentsTypesInSelection', {
18+
const response = await sendCommand('removeFunctionArgumentsTypesInSelection', {
2219
document,
2320
position: selection.start,
2421
inputOptions: {
@@ -37,7 +34,7 @@ export default () => {
3734
const getCurrentValueRange = async () => {
3835
const editor = getActiveRegularEditor()
3936
if (!editor) return
40-
const result = await sendCommand<RequestResponseTypes['getRangeOfSpecialValue']>('getRangeOfSpecialValue')
37+
const result = await sendCommand('getRangeOfSpecialValue')
4138
if (!result) return
4239
const range = tsRangeToVscode(editor.document, result.range)
4340
return range.with({ start: range.start.translate(0, / *{?/.exec(editor.document.lineAt(range.start).text.slice(range.start.character))![0]!.length) })
@@ -121,7 +118,7 @@ export default () => {
121118
registerExtensionCommand('pickAndInsertFunctionArguments', async () => {
122119
const editor = getActiveRegularEditor()
123120
if (!editor) return
124-
const result = await sendCommand<RequestResponseTypes['pickAndInsertFunctionArguments']>('pickAndInsertFunctionArguments')
121+
const result = await sendCommand('pickAndInsertFunctionArguments')
125122
if (!result) return
126123

127124
const renderArgs = (args: Array<[name: string, type: string]>) => `${args.map(([name, type]) => (type ? `${name}: ${type}` : name)).join(', ')}`
@@ -165,7 +162,7 @@ export default () => {
165162
const editor = vscode.window.activeTextEditor
166163
if (!editor) return
167164
const { document } = editor
168-
const result = await sendCommand<RequestResponseTypes['filterBySyntaxKind']>('filterBySyntaxKind')
165+
const result = await sendCommand('filterBySyntaxKind')
169166
if (!result) return
170167
// todo optimize
171168
if (filterWithSelection) {
@@ -228,14 +225,14 @@ export default () => {
228225
document,
229226
selection: { active: position },
230227
} = editor
231-
await sendCommand<RequestOptionsTypes['acceptRenameWithParams']>('acceptRenameWithParams', {
228+
await sendCommand('acceptRenameWithParams', {
232229
document,
233230
position,
234231
inputOptions: {
235232
alias,
236233
comments,
237234
strings,
238-
} satisfies RequestOptionsTypes['acceptRenameWithParams'],
235+
} satisfies RequestInputTypes['acceptRenameWithParams'],
239236
})
240237
await vscode.commands.executeCommand(preview ? 'acceptRenameInputWithPreview' : 'acceptRenameInput')
241238
})
@@ -244,7 +241,7 @@ export default () => {
244241
const editor = vscode.window.activeTextEditor
245242
if (!editor) return
246243
if (!getExtensionSetting('experiments.enableInsertNameOfSuggestionFix') && editor.document.languageId !== 'vue') {
247-
const result = await sendCommand<RequestResponseTypes['getLastResolvedCompletion']>('getLastResolvedCompletion')
244+
const result = await sendCommand('getLastResolvedCompletion')
248245
if (!result) return
249246
const position = editor.selection.active
250247
const range = result.range ? tsRangeToVscode(editor.document, result.range) : editor.document.getWordRangeAtPosition(position)
@@ -283,14 +280,14 @@ export default () => {
283280
})
284281

285282
registerExtensionCommand('copyFullType', async () => {
286-
const response = await sendCommand<RequestResponseTypes['getFullType']>('getFullType')
283+
const response = await sendCommand('getFullType')
287284
if (!response) return
288285
const { text } = response
289286
await vscode.env.clipboard.writeText(text)
290287
})
291288

292289
registerExtensionCommand('getArgumentReferencesFromCurrentParameter', async () => {
293-
const result = await sendCommand<RequestResponseTypes['getArgumentReferencesFromCurrentParameter']>('getArgumentReferencesFromCurrentParameter')
290+
const result = await sendCommand('getArgumentReferencesFromCurrentParameter')
294291
if (!result) return
295292
const editor = vscode.window.activeTextEditor!
296293
const { uri } = editor.document

typescript/src/completionEntryDetails.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { PrevCompletionMap, PrevCompletionsAdditionalData } from './completionsAtPosition'
22
import constructMethodSnippet from './constructMethodSnippet'
3-
import { RequestResponseTypes } from './ipcTypes'
3+
import { RequestOutputTypes } from './ipcTypes'
44
import namespaceAutoImports from './namespaceAutoImports'
55
import { GetConfig } from './types'
66
import { wordStartAtPos } from './utils'
77

88
export const lastResolvedCompletion = {
9-
value: undefined as undefined | RequestResponseTypes['getLastResolvedCompletion'],
9+
value: undefined as undefined | RequestOutputTypes['getLastResolvedCompletion'],
1010
}
1111

1212
export default function completionEntryDetails(

typescript/src/decorateFindRenameLocations.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { RequestOptionsTypes } from './ipcTypes'
1+
import { RequestInputTypes } from './ipcTypes'
22
import { GetConfig } from './types'
33
import { findChildContainingExactPosition } from './utils'
44

55
export const overrideRenameRequest = {
6-
value: undefined as undefined | RequestOptionsTypes['acceptRenameWithParams'],
6+
value: undefined as undefined | RequestInputTypes['acceptRenameWithParams'],
77
}
88

99
export default (proxy: ts.LanguageService, languageService: ts.LanguageService, c: GetConfig) => {

typescript/src/decorateProxy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import lodashGet from 'lodash.get'
22
import { getCompletionsAtPosition, PrevCompletionMap, PrevCompletionsAdditionalData } from './completionsAtPosition'
3-
import { RequestOptionsTypes, TriggerCharacterCommand } from './ipcTypes'
3+
import { RequestInputTypes, TriggerCharacterCommand } from './ipcTypes'
44
import { getNavTreeItems } from './getPatchedNavTree'
55
import decorateCodeActions from './codeActions/decorateProxy'
66
import decorateSemanticDiagnostics from './semanticDiagnostics'

typescript/src/ipcTypes.ts

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,38 @@ export type IpcExtendedCodeAction = {
4242
codes?: number[]
4343
}
4444

45+
// INPUT
46+
export type RequestInputTypes = {
47+
removeFunctionArgumentsTypesInSelection: {
48+
endSelection: number
49+
}
50+
getTwoStepCodeActions: {
51+
range: [number, number]
52+
}
53+
twoStepCodeActionSecondStep: {
54+
range: [number, number]
55+
data: {
56+
name: 'turnArrayIntoObject'
57+
selectedKeyName?: string
58+
}
59+
}
60+
61+
acceptRenameWithParams: {
62+
comments: boolean
63+
strings: boolean
64+
alias: boolean
65+
}
66+
getExtendedCodeActionEdits: {
67+
range: [number, number]
68+
applyCodeActionTitle: string
69+
}
70+
}
71+
4572
// OUTPUT
4673
/**
4774
* @keysSuggestions TriggerCharacterCommand
4875
*/
49-
export type RequestResponseTypes = {
76+
export type RequestOutputTypes = {
5077
removeFunctionArgumentsTypesInSelection: {
5178
ranges: TsRange[]
5279
}
@@ -86,33 +113,7 @@ export type RequestResponseTypes = {
86113
text: string
87114
}
88115
getArgumentReferencesFromCurrentParameter: Array<{ line: number; character: number; filename: string }>
89-
}
90-
91-
// INPUT
92-
export type RequestOptionsTypes = {
93-
removeFunctionArgumentsTypesInSelection: {
94-
endSelection: number
95-
}
96-
getTwoStepCodeActions: {
97-
range: [number, number]
98-
}
99-
twoStepCodeActionSecondStep: {
100-
range: [number, number]
101-
data: {
102-
name: 'turnArrayIntoObject'
103-
selectedKeyName?: string
104-
}
105-
}
106-
107-
acceptRenameWithParams: {
108-
comments: boolean
109-
strings: boolean
110-
alias: boolean
111-
}
112-
getExtendedCodeActionEdits: {
113-
range: [number, number]
114-
applyCodeActionTitle: string
115-
}
116+
'emmet-completions': EmmetResult
116117
}
117118

118119
// export type EmmetResult = {

0 commit comments

Comments
 (0)