@@ -2,7 +2,7 @@ import { compact } from '@zardoy/utils'
2
2
import { getExtendedCodeActions } from '../codeActions/getCodeActions'
3
3
import { NodeAtPositionResponse , RequestInputTypes , RequestOutputTypes , TriggerCharacterCommand , triggerCharacterCommands } from '../ipcTypes'
4
4
import { GetConfig } from '../types'
5
- import { findChildContainingExactPosition , findChildContainingPosition , getNodePath } from '../utils'
5
+ import { findChildContainingExactPosition , findChildContainingPosition , findClosestParent , getNodePath } from '../utils'
6
6
import { lastResolvedCompletion } from '../completionEntryDetails'
7
7
import { overrideRenameRequest } from '../decorateFindRenameLocations'
8
8
import getEmmetCompletions from './emmet'
@@ -254,6 +254,63 @@ export default (
254
254
if ( specialCommand === 'getLastResolvedCompletion' ) {
255
255
return lastResolvedCompletion . value
256
256
}
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
+ }
257
314
if ( specialCommand === 'getFullType' ) {
258
315
const text = getFullType ( languageService , sourceFile , position )
259
316
if ( ! text ) return
0 commit comments