import { getCSSLanguageService } from 'vscode-css-languageservice' ; import { CompletionList , Diagnostic , getLanguageService as getHTMLLanguageService , Position , Range , } from 'vscode-html-languageservice' ; import { TextDocument } from 'vscode-languageserver-textdocument' ; import { getCSSMode } from './modes/cssMode' ; import { getDocumentRegions , HTMLDocumentRegions } from './embeddedSupport' ; import { getHTMLMode } from './modes/htmlMode' ; import { getLanguageModelCache , LanguageModelCache } from './languageModelCache' ; export * from 'vscode-html-languageservice' ; export interface LanguageMode { getId ( ) : string ; doValidation ? : ( document : TextDocument ) => Diagnostic [ ] ; doComplete ? : ( document : TextDocument , position : Position ) => CompletionList ; onDocumentRemoved ( document ) : void ; dispose ( ) : void ; } export interface LanguageModes { getModeAtPosition ( document , position ) : LanguageMode | undefined ; getModesInRange ( document , range ) : LanguageModeRange [ ] ; getAllModes ( ) : LanguageMode [ ] ; getAllModesInDocument ( document ) : LanguageMode [ ] ; getMode ( languageId ) : LanguageMode | undefined ; onDocumentRemoved ( document ) : void ; dispose ( ) : void ; } export interface LanguageModeRange extends Range { mode : LanguageMode | undefined ; attributeValue ? : boolean ; } export function getLanguageModes ( ) { const htmlLanguageService = getHTMLLanguageService ( ) ; const cssLanguageService = getCSSLanguageService ( ) ; const documentRegions = getLanguageModelCache < HTMLDocumentRegions > ( 10 , 60 , document => getDocumentRegions ( htmlLanguageService , document ) ) ; let modelCaches = [ ] ; modelCaches . push ( documentRegions ) ; let modes = Object . create ( null ) ; modes [ 'html' ] = getHTMLMode ( htmlLanguageService ) ; modes [ 'css' ] = getCSSMode ( cssLanguageService , documentRegions ) ; return { getModeAtPosition ( document , position ) { const languageId = documentRegions . get ( document ) . getLanguageAtPosition ( position ) ; if ( languageId ) { return modes [ languageId ] ; } return undefined ; } , getModesInRange ( document , range ) { return documentRegions . get ( document ) . getLanguageRanges ( range ) . map ( r => { return < LanguageModeRange > { start : r . start , end : r . end , mode : r . languageId && modes [ r . languageId ] , attributeValue : r . attributeValue } ; } ) ; } , getAllModesInDocument ( document ) { const result = [ ] ; for ( const languageId of documentRegions . get ( document ) . getLanguagesInDocument ( ) ) { const mode = modes [ languageId ] ; if ( mode ) { result . push ( mode ) ; } } return result ; } , getAllModes ( ) { const result = [ ] ; for ( const languageId in modes ) { const mode = modes [ languageId ] ; if ( mode ) { result . push ( mode ) ; } } return result ; } , getMode ( languageId ) { return modes [ languageId ] ; } , onDocumentRemoved ( document ) { modelCaches . forEach ( mc => mc . onDocumentRemoved ( document ) ) ; for ( const mode in modes ) { modes [ mode ] . onDocumentRemoved ( document ) ; } } , dispose ( ) { modelCaches . forEach ( mc => mc . dispose ( ) ) ; modelCaches = [ ] ; for ( const mode in modes ) { modes [ mode ] . dispose ( ) ; } modes = { } ; } } ; }