make diagnostics settings language-overridable
parent
47f0a8511f
commit
20c41600db
21
package.json
21
package.json
|
@ -73,7 +73,8 @@
|
||||||
"tailwindCSS.validate": {
|
"tailwindCSS.validate": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true,
|
"default": true,
|
||||||
"markdownDescription": ""
|
"markdownDescription": "",
|
||||||
|
"scope": "language-overridable"
|
||||||
},
|
},
|
||||||
"tailwindCSS.lint.utilityConflicts": {
|
"tailwindCSS.lint.utilityConflicts": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
@ -83,7 +84,8 @@
|
||||||
"error"
|
"error"
|
||||||
],
|
],
|
||||||
"default": "warning",
|
"default": "warning",
|
||||||
"markdownDescription": ""
|
"markdownDescription": "",
|
||||||
|
"scope": "language-overridable"
|
||||||
},
|
},
|
||||||
"tailwindCSS.lint.unsupportedApply": {
|
"tailwindCSS.lint.unsupportedApply": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
@ -93,7 +95,8 @@
|
||||||
"error"
|
"error"
|
||||||
],
|
],
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"markdownDescription": ""
|
"markdownDescription": "",
|
||||||
|
"scope": "language-overridable"
|
||||||
},
|
},
|
||||||
"tailwindCSS.lint.unknownScreen": {
|
"tailwindCSS.lint.unknownScreen": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
@ -103,7 +106,8 @@
|
||||||
"error"
|
"error"
|
||||||
],
|
],
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"markdownDescription": ""
|
"markdownDescription": "",
|
||||||
|
"scope": "language-overridable"
|
||||||
},
|
},
|
||||||
"tailwindCSS.lint.unknownVariant": {
|
"tailwindCSS.lint.unknownVariant": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
@ -113,7 +117,8 @@
|
||||||
"error"
|
"error"
|
||||||
],
|
],
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"markdownDescription": ""
|
"markdownDescription": "",
|
||||||
|
"scope": "language-overridable"
|
||||||
},
|
},
|
||||||
"tailwindCSS.lint.unknownConfigKey": {
|
"tailwindCSS.lint.unknownConfigKey": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
@ -123,7 +128,8 @@
|
||||||
"error"
|
"error"
|
||||||
],
|
],
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"markdownDescription": ""
|
"markdownDescription": "",
|
||||||
|
"scope": "language-overridable"
|
||||||
},
|
},
|
||||||
"tailwindCSS.lint.unsupportedTailwindDirective": {
|
"tailwindCSS.lint.unsupportedTailwindDirective": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
@ -133,7 +139,8 @@
|
||||||
"error"
|
"error"
|
||||||
],
|
],
|
||||||
"default": "error",
|
"default": "error",
|
||||||
"markdownDescription": ""
|
"markdownDescription": "",
|
||||||
|
"scope": "language-overridable"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {
|
||||||
OutputChannel,
|
OutputChannel,
|
||||||
WorkspaceFolder,
|
WorkspaceFolder,
|
||||||
Uri,
|
Uri,
|
||||||
|
ConfigurationScope,
|
||||||
} from 'vscode'
|
} from 'vscode'
|
||||||
import {
|
import {
|
||||||
LanguageClient,
|
LanguageClient,
|
||||||
|
@ -22,6 +23,7 @@ import { DEFAULT_LANGUAGES } from './lib/languages'
|
||||||
import isObject from './util/isObject'
|
import isObject from './util/isObject'
|
||||||
import { dedupe, equal } from './util/array'
|
import { dedupe, equal } from './util/array'
|
||||||
import { createEmitter } from './lib/emitter'
|
import { createEmitter } from './lib/emitter'
|
||||||
|
import { onMessage } from './lsp/notifications'
|
||||||
|
|
||||||
const CLIENT_ID = 'tailwindcss-intellisense'
|
const CLIENT_ID = 'tailwindcss-intellisense'
|
||||||
const CLIENT_NAME = 'Tailwind CSS IntelliSense'
|
const CLIENT_NAME = 'Tailwind CSS IntelliSense'
|
||||||
|
@ -150,6 +152,9 @@ export function activate(context: ExtensionContext) {
|
||||||
client.onReady().then(() => {
|
client.onReady().then(() => {
|
||||||
let emitter = createEmitter(client)
|
let emitter = createEmitter(client)
|
||||||
registerConfigErrorHandler(emitter)
|
registerConfigErrorHandler(emitter)
|
||||||
|
onMessage(client, 'getConfiguration', async (scope) => {
|
||||||
|
return Workspace.getConfiguration('tailwindCSS', scope)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
client.start()
|
client.start()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import mitt from 'mitt'
|
import mitt from 'mitt'
|
||||||
import { LanguageClient } from 'vscode-languageclient'
|
import { LanguageClient } from 'vscode-languageclient'
|
||||||
import crypto from 'crypto'
|
import crypto from 'crypto'
|
||||||
|
import { Connection } from 'vscode-languageserver'
|
||||||
|
|
||||||
export interface NotificationEmitter {
|
export interface NotificationEmitter {
|
||||||
on: (name: string, handler: (args: any) => void) => void
|
on: (name: string, handler: (args: any) => void) => void
|
||||||
|
@ -8,7 +9,9 @@ export interface NotificationEmitter {
|
||||||
emit: (name: string, args: any) => Promise<any>
|
emit: (name: string, args: any) => Promise<any>
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createEmitter(client: LanguageClient): NotificationEmitter {
|
export function createEmitter(
|
||||||
|
client: LanguageClient | Connection
|
||||||
|
): NotificationEmitter {
|
||||||
const emitter = mitt()
|
const emitter = mitt()
|
||||||
const registered: string[] = []
|
const registered: string[] = []
|
||||||
|
|
||||||
|
@ -26,7 +29,7 @@ export function createEmitter(client: LanguageClient): NotificationEmitter {
|
||||||
emitter.off(name, handler)
|
emitter.off(name, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
const emit = (name: string, params: any) => {
|
const emit = (name: string, params: Record<string, any> = {}) => {
|
||||||
return new Promise((resolve, _reject) => {
|
return new Promise((resolve, _reject) => {
|
||||||
const id = crypto.randomBytes(16).toString('hex')
|
const id = crypto.randomBytes(16).toString('hex')
|
||||||
on(`${name}Response`, (result) => {
|
on(`${name}Response`, (result) => {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { Connection } from 'vscode-languageserver'
|
import { Connection } from 'vscode-languageserver'
|
||||||
|
import { LanguageClient } from 'vscode-languageclient'
|
||||||
|
|
||||||
export function onMessage(
|
export function onMessage(
|
||||||
connection: Connection,
|
connection: LanguageClient | Connection,
|
||||||
name: string,
|
name: string,
|
||||||
handler: (params: any) => any
|
handler: (params: any) => Thenable<Record<string, any>>
|
||||||
): void {
|
): void {
|
||||||
connection.onNotification(`tailwindcss/${name}`, async (params: any) => {
|
connection.onNotification(`tailwindcss/${name}`, async (params: any) => {
|
||||||
const { _id, ...rest } = params
|
const { _id, ...rest } = params
|
||||||
|
|
|
@ -618,11 +618,11 @@ async function provideEmmetCompletions(
|
||||||
state: State,
|
state: State,
|
||||||
{ position, textDocument }: CompletionParams
|
{ position, textDocument }: CompletionParams
|
||||||
): Promise<CompletionList> {
|
): Promise<CompletionList> {
|
||||||
let settings = await getDocumentSettings(state, textDocument.uri)
|
|
||||||
if (settings.emmetCompletions !== true) return null
|
|
||||||
|
|
||||||
let doc = state.editor.documents.get(textDocument.uri)
|
let doc = state.editor.documents.get(textDocument.uri)
|
||||||
|
|
||||||
|
let settings = await getDocumentSettings(state, doc)
|
||||||
|
if (settings.emmetCompletions !== true) return null
|
||||||
|
|
||||||
const syntax = isHtmlContext(state, doc, position)
|
const syntax = isHtmlContext(state, doc, position)
|
||||||
? 'html'
|
? 'html'
|
||||||
: isJsContext(state, doc, position)
|
: isJsContext(state, doc, position)
|
||||||
|
|
|
@ -376,7 +376,7 @@ export async function provideDiagnostics(
|
||||||
state: State,
|
state: State,
|
||||||
document: TextDocument
|
document: TextDocument
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const settings = await getDocumentSettings(state, document.uri)
|
const settings = await getDocumentSettings(state, document)
|
||||||
|
|
||||||
const diagnostics: Diagnostic[] = settings.validate
|
const diagnostics: Diagnostic[] = settings.validate
|
||||||
? [
|
? [
|
||||||
|
|
|
@ -27,9 +27,10 @@ import { provideHover } from './providers/hoverProvider'
|
||||||
import { URI } from 'vscode-uri'
|
import { URI } from 'vscode-uri'
|
||||||
import { getDocumentSettings } from './util/getDocumentSettings'
|
import { getDocumentSettings } from './util/getDocumentSettings'
|
||||||
import { provideDiagnostics } from './providers/diagnosticsProvider'
|
import { provideDiagnostics } from './providers/diagnosticsProvider'
|
||||||
|
import { createEmitter } from '../lib/emitter'
|
||||||
|
|
||||||
let state: State = { enabled: false }
|
|
||||||
let connection = createConnection(ProposedFeatures.all)
|
let connection = createConnection(ProposedFeatures.all)
|
||||||
|
let state: State = { enabled: false, emitter: createEmitter(connection) }
|
||||||
let documents = new TextDocuments()
|
let documents = new TextDocuments()
|
||||||
let workspaceFolder: string | null
|
let workspaceFolder: string | null
|
||||||
|
|
||||||
|
@ -50,7 +51,7 @@ let globalSettings: Settings = defaultSettings
|
||||||
let documentSettings: Map<string, Settings> = new Map()
|
let documentSettings: Map<string, Settings> = new Map()
|
||||||
|
|
||||||
documents.onDidOpen((event) => {
|
documents.onDidOpen((event) => {
|
||||||
getDocumentSettings(state, event.document.uri)
|
getDocumentSettings(state, event.document)
|
||||||
})
|
})
|
||||||
documents.onDidClose((event) => {
|
documents.onDidClose((event) => {
|
||||||
documentSettings.delete(event.document.uri)
|
documentSettings.delete(event.document.uri)
|
||||||
|
@ -90,14 +91,23 @@ connection.onInitialize(
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
onChange: (newState: State): void => {
|
onChange: (newState: State): void => {
|
||||||
if (newState && !newState.error) {
|
if (newState && !newState.error) {
|
||||||
state = { ...newState, enabled: true, editor: editorState }
|
state = {
|
||||||
|
...newState,
|
||||||
|
enabled: true,
|
||||||
|
emitter: state.emitter,
|
||||||
|
editor: editorState,
|
||||||
|
}
|
||||||
connection.sendNotification('tailwindcss/configUpdated', [
|
connection.sendNotification('tailwindcss/configUpdated', [
|
||||||
state.configPath,
|
state.configPath,
|
||||||
state.config,
|
state.config,
|
||||||
state.plugins,
|
state.plugins,
|
||||||
])
|
])
|
||||||
} else {
|
} else {
|
||||||
state = { enabled: false, editor: editorState }
|
state = {
|
||||||
|
enabled: false,
|
||||||
|
emitter: state.emitter,
|
||||||
|
editor: editorState,
|
||||||
|
}
|
||||||
if (newState && newState.error) {
|
if (newState && newState.error) {
|
||||||
const payload: {
|
const payload: {
|
||||||
message: string
|
message: string
|
||||||
|
@ -120,9 +130,14 @@ connection.onInitialize(
|
||||||
)
|
)
|
||||||
|
|
||||||
if (tailwindState) {
|
if (tailwindState) {
|
||||||
state = { enabled: true, editor: editorState, ...tailwindState }
|
state = {
|
||||||
|
enabled: true,
|
||||||
|
emitter: state.emitter,
|
||||||
|
editor: editorState,
|
||||||
|
...tailwindState,
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
state = { enabled: false, editor: editorState }
|
state = { enabled: false, emitter: state.emitter, editor: editorState }
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
import { State, Settings } from './state'
|
import { State, Settings } from './state'
|
||||||
|
import { TextDocument } from 'vscode-languageserver'
|
||||||
|
|
||||||
export async function getDocumentSettings(
|
export async function getDocumentSettings(
|
||||||
state: State,
|
state: State,
|
||||||
resource: string
|
document: TextDocument
|
||||||
): Promise<Settings> {
|
): Promise<Settings> {
|
||||||
if (!state.editor.capabilities.configuration) {
|
if (!state.editor.capabilities.configuration) {
|
||||||
return Promise.resolve(state.editor.globalSettings)
|
return Promise.resolve(state.editor.globalSettings)
|
||||||
}
|
}
|
||||||
let result = state.editor.documentSettings.get(resource)
|
let result = state.editor.documentSettings.get(document.uri)
|
||||||
if (!result) {
|
if (!result) {
|
||||||
result = await state.editor.connection.workspace.getConfiguration({
|
result = await state.emitter.emit('getConfiguration', {
|
||||||
scopeUri: resource,
|
languageId: document.languageId,
|
||||||
section: 'tailwindCSS',
|
|
||||||
})
|
})
|
||||||
state.editor.documentSettings.set(resource, result)
|
state.editor.documentSettings.set(document.uri, result)
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { TextDocuments, Connection, Range } from 'vscode-languageserver'
|
import { TextDocuments, Connection, Range } from 'vscode-languageserver'
|
||||||
|
import { NotificationEmitter } from '../../lib/emitter'
|
||||||
|
|
||||||
export type ClassNamesTree = {
|
export type ClassNamesTree = {
|
||||||
[key: string]: ClassNamesTree
|
[key: string]: ClassNamesTree
|
||||||
|
@ -43,6 +44,7 @@ export type Settings = {
|
||||||
|
|
||||||
export type State = null | {
|
export type State = null | {
|
||||||
enabled: boolean
|
enabled: boolean
|
||||||
|
emitter: NotificationEmitter
|
||||||
version?: string
|
version?: string
|
||||||
configPath?: string
|
configPath?: string
|
||||||
config?: any
|
config?: any
|
||||||
|
|
Loading…
Reference in New Issue