'use strict' ; import { createConnection , IConnection , Range , TextDocuments , TextDocument , InitializeParams , InitializeResult , RequestType } from 'vscode-languageserver' ; import { getCSSLanguageService , getSCSSLanguageService , getLESSLanguageService , LanguageSettings , LanguageService , Stylesheet } from 'vscode-css-languageservice' ; import { getLanguageModelCache } from './languageModelCache' ; namespace ColorSymbolRequest { export const type = { get method ( ) { return 'css/colorSymbols' ; } } ; } export interface Settings { css : LanguageSettings ; less : LanguageSettings ; scss : LanguageSettings ; } let connection = createConnection ( ) ; console . log = connection . console . log . bind ( connection . console ) ; console . error = connection . console . error . bind ( connection . console ) ; let documents = new TextDocuments ( ) ; documents . listen ( connection ) ; let stylesheets = getLanguageModelCache < Stylesheet > ( 10 , 60 , document => getLanguageService ( document ) . parseStylesheet ( document ) ) ; documents . onDidClose ( e => { stylesheets . onDocumentRemoved ( e . document ) ; } ) ; connection . onShutdown ( ( ) => { stylesheets . dispose ( ) ; } ) ; connection . onInitialize ( ( params ) : InitializeResult => { return { capabilities : { textDocumentSync : documents . syncKind , completionProvider : { resolveProvider : false } , hoverProvider : true , documentSymbolProvider : true , referencesProvider : true , definitionProvider : true , documentHighlightProvider : true , codeActionProvider : true , renameProvider : true } } ; } ) ; let languageServices = { css : getCSSLanguageService ( ) , scss : getSCSSLanguageService ( ) , less : getLESSLanguageService ( ) } ; function getLanguageService ( document ) { let service = languageServices [ document . languageId ] ; if ( ! service ) { connection . console . log ( 'Document type is ' + document . languageId + ', using css instead.' ) ; service = languageServices [ 'css' ] ; } return service ; } connection . onDidChangeConfiguration ( change => { updateConfiguration ( < Settings > change . settings ) ; } ) ; function updateConfiguration ( settings ) { for ( let languageId in languageServices ) { languageServices [ languageId ] . configure ( settings [ languageId ] ) ; } documents . all ( ) . forEach ( triggerValidation ) ; } let pendingValidationRequests = { } ; const validationDelayMs = 200 ; documents . onDidChangeContent ( change => { triggerValidation ( change . document ) ; } ) ; documents . onDidClose ( event => { cleanPendingValidation ( event . document ) ; connection . sendDiagnostics ( { uri : event . document . uri , diagnostics : [ ] } ) ; } ) ; function cleanPendingValidation ( textDocument ) { let request = pendingValidationRequests [ textDocument . uri ] ; if ( request ) { clearTimeout ( request ) ; delete pendingValidationRequests [ textDocument . uri ] ; } } function triggerValidation ( textDocument ) { cleanPendingValidation ( textDocument ) ; pendingValidationRequests [ textDocument . uri ] = setTimeout ( ( ) => { delete pendingValidationRequests [ textDocument . uri ] ; validateTextDocument ( textDocument ) ; } , validationDelayMs ) ; } function validateTextDocument ( textDocument ) { let stylesheet = stylesheets . get ( textDocument ) ; let diagnostics = getLanguageService ( textDocument ) . doValidation ( textDocument , stylesheet ) ; connection . sendDiagnostics ( { uri : textDocument . uri , diagnostics } ) ; } connection . onCompletion ( textDocumentPosition => { let document = documents . get ( textDocumentPosition . textDocument . uri ) ; let stylesheet = stylesheets . get ( document ) ; return getLanguageService ( document ) . doComplete ( document , textDocumentPosition . position , stylesheet ) ; } ) ; connection . onHover ( textDocumentPosition => { let document = documents . get ( textDocumentPosition . textDocument . uri ) ; let styleSheet = stylesheets . get ( document ) ; return getLanguageService ( document ) . doHover ( document , textDocumentPosition . position , styleSheet ) ; } ) ; connection . onDocumentSymbol ( documentSymbolParams => { let document = documents . get ( documentSymbolParams . textDocument . uri ) ; let stylesheet = stylesheets . get ( document ) ; return getLanguageService ( document ) . findDocumentSymbols ( document , stylesheet ) ; } ) ; connection . onDefinition ( documentSymbolParams => { let document = documents . get ( documentSymbolParams . textDocument . uri ) ; let stylesheet = stylesheets . get ( document ) ; return getLanguageService ( document ) . findDefinition ( document , documentSymbolParams . position , stylesheet ) ; } ) ; connection . onDocumentHighlight ( documentSymbolParams => { let document = documents . get ( documentSymbolParams . textDocument . uri ) ; let stylesheet = stylesheets . get ( document ) ; return getLanguageService ( document ) . findDocumentHighlights ( document , documentSymbolParams . position , stylesheet ) ; } ) ; connection . onReferences ( referenceParams => { let document = documents . get ( referenceParams . textDocument . uri ) ; let stylesheet = stylesheets . get ( document ) ; return getLanguageService ( document ) . findReferences ( document , referenceParams . position , stylesheet ) ; } ) ; connection . onCodeAction ( codeActionParams => { let document = documents . get ( codeActionParams . textDocument . uri ) ; let stylesheet = stylesheets . get ( document ) ; return getLanguageService ( document ) . doCodeActions ( document , codeActionParams . range , codeActionParams . context , stylesheet ) ; } ) ; connection . onRequest ( ColorSymbolRequest . type , uri => { let document = documents . get ( uri ) ; let stylesheet = stylesheets . get ( document ) ; return getLanguageService ( document ) . findColorSymbols ( document , stylesheet ) ; } ) ; connection . onRenameRequest ( renameParameters => { let document = documents . get ( renameParameters . textDocument . uri ) ; let stylesheet = stylesheets . get ( document ) ; return getLanguageService ( document ) . doRename ( document , renameParameters . position , renameParameters . newName , stylesheet ) ; } ) ; connection . listen ( ) ;