@@ -2317,6 +2317,118 @@ export class TextModel extends Disposable implements model.ITextModel {
23172317 return null ;
23182318 }
23192319
2320+ public findEnclosingBrackets ( _position : IPosition ) : [ Range , Range ] | null {
2321+ const position = this . validatePosition ( _position ) ;
2322+ const lineCount = this . getLineCount ( ) ;
2323+
2324+ let counts : number [ ] = [ ] ;
2325+ const resetCounts = ( modeBrackets : RichEditBrackets | null ) => {
2326+ counts = [ ] ;
2327+ for ( let i = 0 , len = modeBrackets ? modeBrackets . brackets . length : 0 ; i < len ; i ++ ) {
2328+ counts [ i ] = 0 ;
2329+ }
2330+ } ;
2331+ const searchInRange = ( modeBrackets : RichEditBrackets , lineNumber : number , lineText : string , searchStartOffset : number , searchEndOffset : number ) : [ Range , Range ] | null => {
2332+ while ( true ) {
2333+ const r = BracketsUtils . findNextBracketInRange ( modeBrackets . forwardRegex , lineNumber , lineText , searchStartOffset , searchEndOffset ) ;
2334+ if ( ! r ) {
2335+ break ;
2336+ }
2337+
2338+ const hitText = lineText . substring ( r . startColumn - 1 , r . endColumn - 1 ) . toLowerCase ( ) ;
2339+ const bracket = modeBrackets . textIsBracket [ hitText ] ;
2340+ if ( bracket ) {
2341+ if ( bracket . isOpen ( hitText ) ) {
2342+ counts [ bracket . index ] ++ ;
2343+ } else if ( bracket . isClose ( hitText ) ) {
2344+ counts [ bracket . index ] -- ;
2345+ }
2346+
2347+ if ( counts [ bracket . index ] === - 1 ) {
2348+ return this . _matchFoundBracket ( r , bracket , false ) ;
2349+ }
2350+ }
2351+
2352+ searchStartOffset = r . endColumn - 1 ;
2353+ }
2354+ return null ;
2355+ } ;
2356+
2357+ let languageId : LanguageId = - 1 ;
2358+ let modeBrackets : RichEditBrackets | null = null ;
2359+ for ( let lineNumber = position . lineNumber ; lineNumber <= lineCount ; lineNumber ++ ) {
2360+ const lineTokens = this . _getLineTokens ( lineNumber ) ;
2361+ const tokenCount = lineTokens . getCount ( ) ;
2362+ const lineText = this . _buffer . getLineContent ( lineNumber ) ;
2363+
2364+ let tokenIndex = 0 ;
2365+ let searchStartOffset = 0 ;
2366+ let searchEndOffset = 0 ;
2367+ if ( lineNumber === position . lineNumber ) {
2368+ tokenIndex = lineTokens . findTokenIndexAtOffset ( position . column - 1 ) ;
2369+ searchStartOffset = position . column - 1 ;
2370+ searchEndOffset = position . column - 1 ;
2371+ const tokenLanguageId = lineTokens . getLanguageId ( tokenIndex ) ;
2372+ if ( languageId !== tokenLanguageId ) {
2373+ languageId = tokenLanguageId ;
2374+ modeBrackets = LanguageConfigurationRegistry . getBracketsSupport ( languageId ) ;
2375+ resetCounts ( modeBrackets ) ;
2376+ }
2377+ }
2378+
2379+ let prevSearchInToken = true ;
2380+ for ( ; tokenIndex < tokenCount ; tokenIndex ++ ) {
2381+ const tokenLanguageId = lineTokens . getLanguageId ( tokenIndex ) ;
2382+
2383+ if ( languageId !== tokenLanguageId ) {
2384+ // language id change!
2385+ if ( modeBrackets && prevSearchInToken && searchStartOffset !== searchEndOffset ) {
2386+ const r = searchInRange ( modeBrackets , lineNumber , lineText , searchStartOffset , searchEndOffset ) ;
2387+ if ( r ) {
2388+ return r ;
2389+ }
2390+ prevSearchInToken = false ;
2391+ }
2392+ languageId = tokenLanguageId ;
2393+ modeBrackets = LanguageConfigurationRegistry . getBracketsSupport ( languageId ) ;
2394+ resetCounts ( modeBrackets ) ;
2395+ }
2396+
2397+ const searchInToken = ( ! ! modeBrackets && ! ignoreBracketsInToken ( lineTokens . getStandardTokenType ( tokenIndex ) ) ) ;
2398+ if ( searchInToken ) {
2399+ // this token should be searched
2400+ if ( prevSearchInToken ) {
2401+ // the previous token should be searched, simply extend searchEndOffset
2402+ searchEndOffset = lineTokens . getEndOffset ( tokenIndex ) ;
2403+ } else {
2404+ // the previous token should not be searched
2405+ searchStartOffset = lineTokens . getStartOffset ( tokenIndex ) ;
2406+ searchEndOffset = lineTokens . getEndOffset ( tokenIndex ) ;
2407+ }
2408+ } else {
2409+ // this token should not be searched
2410+ if ( modeBrackets && prevSearchInToken && searchStartOffset !== searchEndOffset ) {
2411+ const r = searchInRange ( modeBrackets , lineNumber , lineText , searchStartOffset , searchEndOffset ) ;
2412+ if ( r ) {
2413+ return r ;
2414+ }
2415+ }
2416+ }
2417+
2418+ prevSearchInToken = searchInToken ;
2419+ }
2420+
2421+ if ( modeBrackets && prevSearchInToken && searchStartOffset !== searchEndOffset ) {
2422+ const r = searchInRange ( modeBrackets , lineNumber , lineText , searchStartOffset , searchEndOffset ) ;
2423+ if ( r ) {
2424+ return r ;
2425+ }
2426+ }
2427+ }
2428+
2429+ return null ;
2430+ }
2431+
23202432 private _toFoundBracket ( modeBrackets : RichEditBrackets , r : Range ) : model . IFoundBracket | null {
23212433 if ( ! r ) {
23222434 return null ;
0 commit comments