2020-04-11 21:20:45 +00:00
|
|
|
/* --------------------------------------------------------------------------------------------
|
|
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
|
|
* ------------------------------------------------------------------------------------------ */
|
|
|
|
|
|
|
|
import {
|
|
|
|
createConnection,
|
|
|
|
TextDocuments,
|
|
|
|
ProposedFeatures,
|
|
|
|
TextDocumentSyncKind,
|
|
|
|
CompletionItem,
|
|
|
|
InitializeParams,
|
|
|
|
InitializeResult,
|
|
|
|
CompletionParams,
|
|
|
|
CompletionList,
|
2020-04-12 14:48:38 +00:00
|
|
|
Hover,
|
|
|
|
TextDocumentPositionParams,
|
2020-04-16 21:39:16 +00:00
|
|
|
DidChangeConfigurationNotification,
|
2020-04-11 21:20:45 +00:00
|
|
|
} from 'vscode-languageserver'
|
2020-05-03 14:57:15 +00:00
|
|
|
import getTailwindState from '../class-names/index'
|
2020-04-22 19:29:36 +00:00
|
|
|
import { State, Settings, EditorState } from './util/state'
|
2020-04-11 21:20:45 +00:00
|
|
|
import {
|
|
|
|
provideCompletions,
|
|
|
|
resolveCompletionItem,
|
|
|
|
} from './providers/completionProvider'
|
2020-04-12 14:48:38 +00:00
|
|
|
import { provideHover } from './providers/hoverProvider'
|
2020-04-11 21:20:45 +00:00
|
|
|
import { URI } from 'vscode-uri'
|
2020-04-16 21:39:16 +00:00
|
|
|
import { getDocumentSettings } from './util/getDocumentSettings'
|
2020-05-09 21:11:35 +00:00
|
|
|
import { provideDiagnostics } from './providers/diagnosticsProvider'
|
2020-04-11 21:20:45 +00:00
|
|
|
|
2020-04-22 19:29:36 +00:00
|
|
|
let state: State = { enabled: false }
|
2020-04-11 21:20:45 +00:00
|
|
|
let connection = createConnection(ProposedFeatures.all)
|
|
|
|
let documents = new TextDocuments()
|
|
|
|
let workspaceFolder: string | null
|
|
|
|
|
2020-05-03 17:11:45 +00:00
|
|
|
const defaultSettings: Settings = {
|
|
|
|
emmetCompletions: false,
|
|
|
|
includeLanguages: {},
|
2020-06-12 15:22:04 +00:00
|
|
|
validate: true,
|
|
|
|
lint: {
|
|
|
|
utilityConflicts: 'warning',
|
|
|
|
unsupportedApply: 'error',
|
2020-06-12 15:41:49 +00:00
|
|
|
unknownScreen: 'error',
|
2020-06-12 15:56:02 +00:00
|
|
|
unknownVariant: 'error',
|
2020-06-12 16:16:54 +00:00
|
|
|
unknownConfigKey: 'error',
|
2020-06-12 15:22:04 +00:00
|
|
|
},
|
2020-05-03 17:11:45 +00:00
|
|
|
}
|
2020-04-16 21:39:16 +00:00
|
|
|
let globalSettings: Settings = defaultSettings
|
|
|
|
let documentSettings: Map<string, Settings> = new Map()
|
|
|
|
|
2020-04-11 21:20:45 +00:00
|
|
|
documents.onDidOpen((event) => {
|
2020-04-16 21:39:16 +00:00
|
|
|
getDocumentSettings(state, event.document.uri)
|
|
|
|
})
|
|
|
|
documents.onDidClose((event) => {
|
|
|
|
documentSettings.delete(event.document.uri)
|
2020-04-11 21:20:45 +00:00
|
|
|
})
|
2020-05-09 21:11:35 +00:00
|
|
|
documents.onDidChangeContent((change) => {
|
|
|
|
provideDiagnostics(state, change.document)
|
|
|
|
})
|
2020-04-11 21:20:45 +00:00
|
|
|
documents.listen(connection)
|
|
|
|
|
|
|
|
connection.onInitialize(
|
|
|
|
async (params: InitializeParams): Promise<InitializeResult> => {
|
2020-04-22 19:29:36 +00:00
|
|
|
const capabilities = params.capabilities
|
|
|
|
|
|
|
|
const editorState: EditorState = {
|
|
|
|
connection,
|
|
|
|
documents,
|
|
|
|
documentSettings,
|
|
|
|
globalSettings,
|
2020-05-03 17:11:45 +00:00
|
|
|
userLanguages:
|
|
|
|
params.initializationOptions &&
|
|
|
|
params.initializationOptions.userLanguages
|
|
|
|
? params.initializationOptions.userLanguages
|
|
|
|
: {},
|
2020-04-22 19:29:36 +00:00
|
|
|
capabilities: {
|
|
|
|
configuration:
|
|
|
|
capabilities.workspace && !!capabilities.workspace.configuration,
|
2020-05-09 21:11:35 +00:00
|
|
|
diagnosticRelatedInformation:
|
|
|
|
capabilities.textDocument &&
|
|
|
|
capabilities.textDocument.publishDiagnostics &&
|
|
|
|
capabilities.textDocument.publishDiagnostics.relatedInformation,
|
2020-04-22 19:29:36 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
const tailwindState = await getTailwindState(
|
2020-04-11 21:20:45 +00:00
|
|
|
params.rootPath || URI.parse(params.rootUri).path,
|
|
|
|
{
|
2020-05-03 14:57:15 +00:00
|
|
|
// @ts-ignore
|
2020-04-11 21:20:45 +00:00
|
|
|
onChange: (newState: State): void => {
|
2020-04-23 18:54:01 +00:00
|
|
|
if (newState && !newState.error) {
|
2020-04-22 19:29:36 +00:00
|
|
|
state = { ...newState, enabled: true, editor: editorState }
|
|
|
|
connection.sendNotification('tailwindcss/configUpdated', [
|
|
|
|
state.configPath,
|
|
|
|
state.config,
|
|
|
|
state.plugins,
|
|
|
|
])
|
|
|
|
} else {
|
|
|
|
state = { enabled: false, editor: editorState }
|
2020-04-23 18:54:01 +00:00
|
|
|
if (newState && newState.error) {
|
|
|
|
const payload: {
|
|
|
|
message: string
|
|
|
|
file?: string
|
|
|
|
line?: number
|
|
|
|
} = { message: newState.error.message }
|
|
|
|
const lines = newState.error.stack.toString().split('\n')
|
|
|
|
const match = /^(?<file>.*?):(?<line>[0-9]+)$/.exec(lines[0])
|
|
|
|
if (match) {
|
|
|
|
payload.file = match.groups.file
|
|
|
|
payload.line = parseInt(match.groups.line, 10)
|
|
|
|
}
|
|
|
|
connection.sendNotification('tailwindcss/configError', [payload])
|
|
|
|
}
|
2020-04-22 19:29:36 +00:00
|
|
|
// TODO
|
|
|
|
// connection.sendNotification('tailwindcss/configUpdated', [null])
|
|
|
|
}
|
2020-04-11 21:20:45 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
)
|
2020-04-16 21:39:16 +00:00
|
|
|
|
2020-04-22 19:29:36 +00:00
|
|
|
if (tailwindState) {
|
|
|
|
state = { enabled: true, editor: editorState, ...tailwindState }
|
|
|
|
} else {
|
|
|
|
state = { enabled: false, editor: editorState }
|
2020-04-16 21:39:16 +00:00
|
|
|
}
|
2020-04-11 21:20:45 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
capabilities: {
|
|
|
|
// textDocumentSync: {
|
|
|
|
// openClose: true,
|
|
|
|
// change: TextDocumentSyncKind.None
|
|
|
|
// },
|
|
|
|
textDocumentSync: documents.syncKind,
|
|
|
|
completionProvider: {
|
|
|
|
resolveProvider: true,
|
2020-04-22 19:29:36 +00:00
|
|
|
triggerCharacters: [
|
|
|
|
// class attributes
|
|
|
|
'"',
|
|
|
|
"'",
|
|
|
|
'`',
|
|
|
|
// between class names
|
|
|
|
' ',
|
|
|
|
// @apply and emmet-style
|
|
|
|
'.',
|
|
|
|
// config/theme helper
|
|
|
|
'[',
|
|
|
|
// TODO: restart server if separater changes?
|
|
|
|
typeof state.separator === 'undefined' ? ':' : state.separator,
|
|
|
|
],
|
2020-04-11 21:20:45 +00:00
|
|
|
},
|
2020-04-12 14:48:38 +00:00
|
|
|
hoverProvider: true,
|
2020-04-11 21:20:45 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
connection.onInitialized &&
|
|
|
|
connection.onInitialized(async () => {
|
2020-04-16 21:39:16 +00:00
|
|
|
if (state.editor.capabilities.configuration) {
|
|
|
|
connection.client.register(
|
|
|
|
DidChangeConfigurationNotification.type,
|
|
|
|
undefined
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2020-04-11 21:20:45 +00:00
|
|
|
connection.sendNotification('tailwindcss/configUpdated', [
|
2020-04-22 19:29:36 +00:00
|
|
|
state.configPath,
|
2020-04-11 21:20:45 +00:00
|
|
|
state.config,
|
|
|
|
state.plugins,
|
|
|
|
])
|
|
|
|
})
|
|
|
|
|
2020-04-16 21:39:16 +00:00
|
|
|
connection.onDidChangeConfiguration((change) => {
|
|
|
|
if (state.editor.capabilities.configuration) {
|
|
|
|
// Reset all cached document settings
|
|
|
|
state.editor.documentSettings.clear()
|
|
|
|
} else {
|
|
|
|
state.editor.globalSettings = <Settings>(
|
|
|
|
(change.settings.tailwindCSS || defaultSettings)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2020-06-12 15:22:04 +00:00
|
|
|
state.editor.documents.all().forEach((doc) => {
|
|
|
|
provideDiagnostics(state, doc)
|
|
|
|
})
|
2020-04-16 21:39:16 +00:00
|
|
|
})
|
|
|
|
|
2020-04-11 21:20:45 +00:00
|
|
|
connection.onCompletion(
|
2020-04-16 21:39:16 +00:00
|
|
|
(params: CompletionParams): Promise<CompletionList> => {
|
2020-04-22 19:29:36 +00:00
|
|
|
if (!state.enabled) return null
|
2020-04-11 21:20:45 +00:00
|
|
|
return provideCompletions(state, params)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
|
|
|
connection.onCompletionResolve(
|
|
|
|
(item: CompletionItem): CompletionItem => {
|
2020-04-22 19:29:36 +00:00
|
|
|
if (!state.enabled) return null
|
2020-04-11 21:20:45 +00:00
|
|
|
return resolveCompletionItem(state, item)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2020-04-12 14:48:38 +00:00
|
|
|
connection.onHover(
|
|
|
|
(params: TextDocumentPositionParams): Hover => {
|
2020-04-22 19:29:36 +00:00
|
|
|
if (!state.enabled) return null
|
2020-04-12 14:48:38 +00:00
|
|
|
return provideHover(state, params)
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2020-04-11 21:20:45 +00:00
|
|
|
connection.listen()
|