import * as path from 'path' ; import * as vscode from 'vscode' ; const tm = loadTextMate ( ) ; function getNodeModule ( moduleName ) { try { console . log ( `${ vscode . env . appRoot }/node_modules.asar/${ moduleName }` ) ; return require ( `${ vscode . env . appRoot }/node_modules.asar/${ moduleName }` ) ; } catch ( err ) { } try { console . log ( `>>> ${ vscode . env . appRoot }/node_modules/${ moduleName }` ) ; return require ( `${ vscode . env . appRoot }/node_modules/${ moduleName }` ) ; } catch ( err ) { } return null ; } function loadTextMate ( ) { return getNodeModule ( 'vscode-textmate' ) ; } export function matchScope ( scope , scopes ) { if ( ! scope ) return true ; const parts = scope . split ( /\s+/ ) ; let idx = 0 ; for ( let part of parts ) { while ( idx < scopes . length && ! scopes [ idx ] . startsWith ( part ) ) ++ idx ; if ( idx >= scopes . length ) return false ; ++ idx ; } return true ; } export interface Registry { new ( locator ? ) ; /**
     * Load the grammar for `scopeName` and all referenced included grammars asynchronously.
     */ loadGrammar ( initialScopeName , callback ) : void ; /**
     * Load the grammar at `path` synchronously.
     */ loadGrammarFromPathSync ( path ) : IGrammar ; /**
     * Get the grammar for `scopeName`. The grammar must first be created via `loadGrammar` or `loadGrammarFromPathSync`.
     */ grammarForScopeName ( scopeName ) : IGrammar ; } const dummyGrammar = { tokenizeLine ( lineText , prevState ) { return { tokens : [ ] , ruleStack : prevState , } ; } } ; class DummyRegistry { public constructor ( locator ? ) { } loadGrammar ( initialScopeName , callback ) { callback ( new Error ( "textmate cannot be loaded" ) , undefined ) ; } loadGrammarFromPathSync ( path ) { return dummyGrammar ; } grammarForScopeName ( scopeName ) { return dummyGrammar ; } } export const Registry = tm == null ? ( DummyRegistry as any ) : tm . Registry ; /**
 * A registry helper that can locate grammar file paths given scope names.
 */ export interface IGrammarLocator { getFilePath ( scopeName ) : string ; getInjections ? ( scopeName ) : string [ ] ; } export interface IGrammarInfo { readonly fileTypes : string [ ] ; readonly name : string ; readonly scopeName : string ; readonly firstLineMatch : string ; } /**
 * A grammar
 */ export interface IGrammar { /**
     * Tokenize `lineText` using previous line state `prevState`.
     */ tokenizeLine ( lineText , prevState ) : ITokenizeLineResult ; } export interface ITokenizeLineResult { readonly tokens : IToken [ ] ; /**
     * The `prevState` to be passed on to the next line tokenization.
     */ readonly ruleStack : StackElement ; } export interface IToken { startIndex : number ; readonly endIndex : number ; readonly scopes : string [ ] ; } /**
 * **IMPORTANT** - Immutable!
 */ export interface StackElement { _stackElementBrand : void ; readonly _parent : StackElement ; equals ( other ) : boolean ; } export function combineIdenticalTokenScopes ( tokens ) { if ( ! tokens || tokens . length === 0 ) return [ ] ; const result = [ tokens [ 0 ] ] ; let prevToken = tokens [ 0 ] ; for ( let idx = 1 ; idx < tokens . length ; ++ idx ) { const token = tokens [ idx ] ; if ( prevToken . endIndex === token . startIndex && token . scopes . length === prevToken . scopes . length && token . scopes . every ( ( t , idx ) => t === prevToken . scopes [ idx ] ) ) { result [ result . length - 1 ] = { startIndex : prevToken . startIndex , endIndex : token . endIndex , scopes : prevToken . scopes } ; prevToken = result [ result . length - 1 ] ; } else { result . push ( token ) ; prevToken = token ; } } return result ; }