11import * as vscode from 'vscode'
2- import { getActiveRegularEditor , rangeToSelection } from '@zardoy/vscode-utils'
3- import { getExtensionCommandId , registerExtensionCommand , VSCodeQuickPickItem } from 'vscode-framework'
2+ import { getActiveRegularEditor } from '@zardoy/vscode-utils'
3+ import { getExtensionCommandId , getExtensionSetting , registerExtensionCommand , VSCodeQuickPickItem } from 'vscode-framework'
44import { showQuickPick } from '@zardoy/vscode-utils/build/quickPick'
55import _ from 'lodash'
66import { compact } from '@zardoy/utils'
7+ import { defaultJsSupersetLangsWithVue } from '@zardoy/vscode-utils/build/langs'
8+ import { offsetPosition } from '@zardoy/vscode-utils/build/position'
79import { RequestOptionsTypes , RequestResponseTypes } from '../typescript/src/ipcTypes'
810import { sendCommand } from './sendCommand'
911import { tsRangeToVscode , tsRangeToVscodeSelection } from './util'
@@ -13,12 +15,15 @@ export default () => {
1315 const editor = getActiveRegularEditor ( )
1416 if ( ! editor ) return
1517 const { selection, document } = editor
16- const response = await sendCommand < RequestResponseTypes [ 'removeFunctionArgumentsTypesInSelection' ] > ( 'removeFunctionArgumentsTypesInSelection' , {
18+ const response = await sendCommand <
19+ RequestResponseTypes [ 'removeFunctionArgumentsTypesInSelection' ] ,
20+ RequestOptionsTypes [ 'removeFunctionArgumentsTypesInSelection' ]
21+ > ( 'removeFunctionArgumentsTypesInSelection' , {
1722 document,
1823 position : selection . start ,
1924 inputOptions : {
2025 endSelection : document . offsetAt ( selection . end ) ,
21- } as RequestOptionsTypes [ 'removeFunctionArgumentsTypesInSelection' ] ,
26+ } ,
2227 } )
2328 if ( ! response ) return
2429 const { ranges } = response
@@ -215,4 +220,79 @@ export default () => {
215220 registerExtensionCommand ( 'goToNodeBySyntaxKindWithinSelection' , async ( ) => {
216221 await vscode . commands . executeCommand ( getExtensionCommandId ( 'goToNodeBySyntaxKind' ) , { filterWithSelection : true } )
217222 } )
223+
224+ async function sendTurnIntoArrayRequest < T = RequestResponseTypes [ 'turnArrayIntoObject' ] > (
225+ range : vscode . Range ,
226+ selectedKeyName ?: string ,
227+ document = vscode . window . activeTextEditor ! . document ,
228+ ) {
229+ return sendCommand < T , RequestOptionsTypes [ 'turnArrayIntoObject' ] > ( 'turnArrayIntoObject' , {
230+ document,
231+ position : range . start ,
232+ inputOptions : {
233+ range : [ document . offsetAt ( range . start ) , document . offsetAt ( range . end ) ] as [ number , number ] ,
234+ selectedKeyName,
235+ } ,
236+ } )
237+ }
238+
239+ registerExtensionCommand ( 'turnArrayIntoObjectRefactoring' as any , async ( _ , arg ?: RequestResponseTypes [ 'turnArrayIntoObject' ] ) => {
240+ if ( ! arg ) return
241+ const { keysCount, totalCount, totalObjectCount } = arg
242+ const selectedKey : string | false | undefined =
243+ // eslint-disable-next-line @typescript-eslint/dot-notation
244+ arg [ 'key' ] ||
245+ ( await showQuickPick (
246+ Object . entries ( keysCount ) . map ( ( [ key , count ] ) => {
247+ const isAllowed = count === totalObjectCount
248+ return { label : `${ isAllowed ? '$(check)' : '$(close)' } ${ key } ` , value : isAllowed ? key : false , description : `${ count } hits` }
249+ } ) ,
250+ {
251+ title : `Selected available key from ${ totalObjectCount } objects (${ totalCount } elements)` ,
252+ } ,
253+ ) )
254+ if ( selectedKey === undefined || selectedKey === '' ) return
255+ if ( selectedKey === false ) {
256+ void vscode . window . showWarningMessage ( "Can't use selected key as its not used in every object" )
257+ return
258+ }
259+
260+ const editor = vscode . window . activeTextEditor !
261+ const edits = await sendTurnIntoArrayRequest < RequestResponseTypes [ 'turnArrayIntoObjectEdit' ] > ( editor . selection , selectedKey )
262+ if ( ! edits ) throw new Error ( 'Unknown error. Try debug.' )
263+ await editor . edit ( builder => {
264+ for ( const { span, newText } of edits ) {
265+ const start = editor . document . positionAt ( span . start )
266+ builder . replace ( new vscode . Range ( start , offsetPosition ( editor . document , start , span . length ) ) , newText )
267+ }
268+ } )
269+ } )
270+
271+ // its actually a code action, but will be removed from there soon
272+ vscode . languages . registerCodeActionsProvider ( defaultJsSupersetLangsWithVue , {
273+ async provideCodeActions ( document , range , context , token ) {
274+ if (
275+ context . triggerKind !== vscode . CodeActionTriggerKind . Invoke ||
276+ document !== vscode . window . activeTextEditor ?. document ||
277+ ! getExtensionSetting ( 'enablePlugin' )
278+ )
279+ return
280+ const result = await sendTurnIntoArrayRequest ( range )
281+ if ( ! result ) return
282+ const { keysCount, totalCount, totalObjectCount } = result
283+ return [
284+ {
285+ title : `Turn Array Into Object (${ totalCount } elements)` ,
286+ command : getExtensionCommandId ( 'turnArrayIntoObjectRefactoring' as any ) ,
287+ arguments : [
288+ {
289+ keysCount,
290+ totalCount,
291+ totalObjectCount,
292+ } satisfies RequestResponseTypes [ 'turnArrayIntoObject' ] ,
293+ ] ,
294+ } ,
295+ ]
296+ } ,
297+ } )
218298}
0 commit comments