@@ -2,7 +2,7 @@ import { compact } from '@zardoy/utils'
22import { getExtendedCodeActions } from '../codeActions/getCodeActions'
33import { NodeAtPositionResponse , RequestInputTypes , RequestOutputTypes , TriggerCharacterCommand , triggerCharacterCommands } from '../ipcTypes'
44import { GetConfig } from '../types'
5- import { findChildContainingExactPosition , findChildContainingPosition , getNodePath } from '../utils'
5+ import { findChildContainingExactPosition , findChildContainingPosition , findClosestParent , getNodePath } from '../utils'
66import { lastResolvedCompletion } from '../completionEntryDetails'
77import { overrideRenameRequest } from '../decorateFindRenameLocations'
88import getEmmetCompletions from './emmet'
@@ -254,6 +254,63 @@ export default (
254254 if ( specialCommand === 'getLastResolvedCompletion' ) {
255255 return lastResolvedCompletion . value
256256 }
257+ if ( specialCommand === 'searchWorkspaceBySyntaxKind' || specialCommand === 'searchWorkspaceBySyntaxKindPrepare' ) {
258+ const files = languageService
259+ . getProgram ( ) !
260+ . getSourceFiles ( )
261+ . filter ( x => ! x . fileName . includes ( 'node_modules' ) && ! x . fileName . includes ( 'dist' ) && ! x . fileName . includes ( 'build' ) )
262+ const excludeKinds : Array < keyof typeof ts . SyntaxKind > = [ 'SourceFile' ]
263+ const allowKinds : Array < keyof typeof ts . SyntaxKind > = [ 'ReturnStatement' ]
264+ if ( specialCommand === 'searchWorkspaceBySyntaxKind' ) {
265+ changeType < RequestInputTypes [ 'searchWorkspaceBySyntaxKind' ] > ( specialCommandArg )
266+
267+ const collectedNodes : RequestOutputTypes [ 'searchWorkspaceBySyntaxKind' ] [ 'files' ] = [ ]
268+ for ( const file of files ) {
269+ let lastIndex = 0
270+ while ( lastIndex !== - 1 ) {
271+ lastIndex = file . text . indexOf ( specialCommandArg . query , lastIndex + 1 )
272+ if ( lastIndex === - 1 ) continue
273+ const node = findChildContainingExactPosition ( file , lastIndex )
274+ if ( ! node || ! specialCommandArg . kinds . includes ( ts . SyntaxKind [ node . kind ] ! ) ) continue
275+
276+ // ignore imports for now...
277+ const importDecl = findClosestParent ( node , [ ts . SyntaxKind . ImportDeclaration , ts . SyntaxKind . ExportDeclaration ] , [ ] )
278+ if ( importDecl ) continue
279+
280+ const fileRanges = collectedNodes . find ( x => x . filename === file . fileName )
281+ let start = node . pos + ( specialCommandArg . kinds . includes ( 'comment' ) ? 0 : node . getLeadingTriviaWidth ( file ) )
282+ let endPos = node . end
283+ start += lastIndex - start
284+ endPos -= node . end - ( lastIndex + specialCommandArg . query . length )
285+ const range = [ start , endPos ] as [ number , number ]
286+ if ( fileRanges ) {
287+ fileRanges . ranges . push ( range )
288+ } else {
289+ collectedNodes . push ( { filename : file . fileName , ranges : [ range ] } )
290+ }
291+ }
292+ }
293+
294+ return {
295+ files : collectedNodes ,
296+ } satisfies RequestOutputTypes [ 'searchWorkspaceBySyntaxKind' ]
297+ }
298+ if ( specialCommand === 'searchWorkspaceBySyntaxKindPrepare' ) {
299+ const kinds = Object . values ( ts . SyntaxKind ) as Array < string | number >
300+ return {
301+ syntaxKinds : kinds . filter (
302+ kind =>
303+ allowKinds . includes ( kind as any ) ||
304+ ( typeof kind === 'string' &&
305+ ! excludeKinds . includes ( kind as any ) &&
306+ ! kind . includes ( 'Token' ) &&
307+ ! kind . includes ( 'Statement' ) &&
308+ ! kind . includes ( 'Operator' ) ) ,
309+ ) as string [ ] ,
310+ filesCount : files . length ,
311+ } satisfies RequestOutputTypes [ 'searchWorkspaceBySyntaxKindPrepare' ]
312+ }
313+ }
257314 if ( specialCommand === 'getFullType' ) {
258315 const text = getFullType ( languageService , sourceFile , position )
259316 if ( ! text ) return
0 commit comments