Add `files.exclude` setting
parent
6fdef8616a
commit
ff52e815b6
|
@ -1,12 +1,17 @@
|
|||
import { TextDocument } from 'vscode-languageserver/node'
|
||||
import { State } from 'tailwindcss-language-service/src/util/state'
|
||||
import { doValidate } from 'tailwindcss-language-service/src/diagnostics/diagnosticsProvider'
|
||||
import isExcluded from '../util/isExcluded'
|
||||
|
||||
export async function provideDiagnostics(state: State, document: TextDocument) {
|
||||
state.editor?.connection.sendDiagnostics({
|
||||
uri: document.uri,
|
||||
diagnostics: await doValidate(state, document),
|
||||
})
|
||||
if (await isExcluded(state, document)) {
|
||||
clearDiagnostics(state, document)
|
||||
} else {
|
||||
state.editor?.connection.sendDiagnostics({
|
||||
uri: document.uri,
|
||||
diagnostics: await doValidate(state, document),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function clearDiagnostics(state: State, document: TextDocument): void {
|
||||
|
|
|
@ -78,6 +78,9 @@ import * as culori from 'culori'
|
|||
import namedColors from 'color-name'
|
||||
import preflight from './lib/preflight'
|
||||
import tailwindPlugins from './lib/plugins'
|
||||
import isExcluded from './util/isExcluded'
|
||||
import { getFileFsPath, normalizeFileNameToFsPath } from './util/uri'
|
||||
import { equal } from 'tailwindcss-language-service/src/util/array'
|
||||
|
||||
let oldReadFileSync = fs.readFileSync
|
||||
// @ts-ignore
|
||||
|
@ -121,14 +124,6 @@ process.on('unhandledRejection', (e: any) => {
|
|||
connection.console.error(formatError(`Unhandled exception`, e))
|
||||
})
|
||||
|
||||
function normalizeFileNameToFsPath(fileName: string) {
|
||||
return URI.file(fileName).fsPath
|
||||
}
|
||||
|
||||
function getFileFsPath(documentUri: string): string {
|
||||
return URI.parse(documentUri).fsPath
|
||||
}
|
||||
|
||||
function deletePropertyPath(obj: any, path: string | string[]): void {
|
||||
if (typeof path === 'string') {
|
||||
path = path.split('.')
|
||||
|
@ -220,6 +215,7 @@ async function createProjectService(
|
|||
enabled: false,
|
||||
editor: {
|
||||
connection,
|
||||
folder,
|
||||
globalSettings: params.initializationOptions.configuration as Settings,
|
||||
userLanguages: params.initializationOptions.userLanguages
|
||||
? params.initializationOptions.userLanguages
|
||||
|
@ -258,12 +254,7 @@ async function createProjectService(
|
|||
let registrations: Promise<BulkUnregistration>
|
||||
|
||||
let chokidarWatcher: chokidar.FSWatcher
|
||||
let ignore = [
|
||||
'**/.git/objects/**',
|
||||
'**/.git/subtree-cache/**',
|
||||
'**/node_modules/**',
|
||||
'**/.hg/store/**',
|
||||
]
|
||||
let ignore = state.editor.globalSettings.tailwindCSS.files.exclude
|
||||
|
||||
function onFileEvents(changes: Array<{ file: string; type: FileChangeType }>): void {
|
||||
let needsInit = false
|
||||
|
@ -456,7 +447,7 @@ async function createProjectService(
|
|||
let [configPath] = (
|
||||
await glob([`**/${CONFIG_FILE_GLOB}`], {
|
||||
cwd: folder,
|
||||
ignore: ['**/node_modules'],
|
||||
ignore: state.editor.globalSettings.tailwindCSS.files.exclude,
|
||||
onlyFiles: true,
|
||||
absolute: true,
|
||||
suppressErrors: true,
|
||||
|
@ -989,25 +980,33 @@ async function createProjectService(
|
|||
},
|
||||
onUpdateSettings(settings: any): void {
|
||||
documentSettingsCache.clear()
|
||||
if (state.enabled) {
|
||||
updateAllDiagnostics(state)
|
||||
}
|
||||
if (settings.editor.colorDecorators) {
|
||||
registerCapabilities(state.dependencies)
|
||||
let previousExclude = state.editor.globalSettings.tailwindCSS.files.exclude
|
||||
state.editor.globalSettings = settings
|
||||
if (!equal(previousExclude, settings.tailwindCSS.files.exclude)) {
|
||||
tryInit()
|
||||
} else {
|
||||
connection.sendNotification('@/tailwindCSS/clearColors')
|
||||
if (state.enabled) {
|
||||
updateAllDiagnostics(state)
|
||||
}
|
||||
if (settings.editor.colorDecorators) {
|
||||
registerCapabilities(state.dependencies)
|
||||
} else {
|
||||
connection.sendNotification('@/tailwindCSS/clearColors')
|
||||
}
|
||||
}
|
||||
},
|
||||
onHover(params: TextDocumentPositionParams): Promise<Hover> {
|
||||
async onHover(params: TextDocumentPositionParams): Promise<Hover> {
|
||||
if (!state.enabled) return null
|
||||
let document = documentService.getDocument(params.textDocument.uri)
|
||||
if (!document) return null
|
||||
if (await isExcluded(state, document)) return null
|
||||
return doHover(state, document, params.position)
|
||||
},
|
||||
onCompletion(params: CompletionParams): Promise<CompletionList> {
|
||||
async onCompletion(params: CompletionParams): Promise<CompletionList> {
|
||||
if (!state.enabled) return null
|
||||
let document = documentService.getDocument(params.textDocument.uri)
|
||||
if (!document) return null
|
||||
if (await isExcluded(state, document)) return null
|
||||
return doComplete(state, document, params.position, params.context)
|
||||
},
|
||||
onCompletionResolve(item: CompletionItem): Promise<CompletionItem> {
|
||||
|
@ -1026,6 +1025,7 @@ async function createProjectService(
|
|||
if (!state.enabled) return []
|
||||
let document = documentService.getDocument(params.textDocument.uri)
|
||||
if (!document) return []
|
||||
if (await isExcluded(state, document)) return null
|
||||
return getDocumentColors(state, document)
|
||||
},
|
||||
async onColorPresentation(params: ColorPresentationParams): Promise<ColorPresentation[]> {
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import minimatch from 'minimatch'
|
||||
import * as path from 'path'
|
||||
import { State } from 'tailwindcss-language-service/src/util/state'
|
||||
import { TextDocument } from 'vscode-languageserver-textdocument'
|
||||
import { getFileFsPath } from './uri'
|
||||
|
||||
export default async function isExcluded(state: State, document: TextDocument): Promise<boolean> {
|
||||
let settings = await state.editor.getConfiguration(document.uri)
|
||||
let file = getFileFsPath(document.uri)
|
||||
|
||||
for (let pattern of settings.tailwindCSS.files.exclude) {
|
||||
if (minimatch(file, path.join(state.editor.folder, pattern))) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
import { URI } from 'vscode-uri'
|
||||
|
||||
export function normalizeFileNameToFsPath(fileName: string) {
|
||||
return URI.file(fileName).fsPath
|
||||
}
|
||||
|
||||
export function getFileFsPath(documentUri: string): string {
|
||||
return URI.parse(documentUri).fsPath
|
||||
}
|
|
@ -19,6 +19,7 @@ export type ClassNames = {
|
|||
|
||||
export type EditorState = {
|
||||
connection: Connection
|
||||
folder: string
|
||||
documents: TextDocuments<TextDocument>
|
||||
globalSettings: Settings
|
||||
userLanguages: Record<string, string>
|
||||
|
@ -56,6 +57,9 @@ export type Settings = {
|
|||
experimental: {
|
||||
classRegex: string[]
|
||||
}
|
||||
files: {
|
||||
exclude: string[]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -62,6 +62,10 @@ This setting allows you to add additional language support. The key of each entr
|
|||
}
|
||||
```
|
||||
|
||||
### `tailwindCSS.files.exclude`
|
||||
|
||||
Configure glob patterns to exclude from all IntelliSense features. Inherits all glob patterns from the `files.exclude` setting. **Default: ["\*\*/.git/\*\*", "\*\*/node_modules/\*\*", "\*\*/.hg/\*\*"]**
|
||||
|
||||
### `tailwindCSS.emmetCompletions`
|
||||
|
||||
Enable completions when using [Emmet](https://emmet.io/)-style syntax, for example `div.bg-red-500.uppercase`. **Default: `false`**
|
||||
|
|
|
@ -119,6 +119,18 @@
|
|||
"default": {},
|
||||
"markdownDescription": "Enable features in languages that are not supported by default. Add a mapping here between the new language and an already supported language.\n E.g.: `{\"plaintext\": \"html\"}`"
|
||||
},
|
||||
"tailwindCSS.files.exclude": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"default": [
|
||||
"**/.git/**",
|
||||
"**/node_modules/**",
|
||||
"**/.hg/**"
|
||||
],
|
||||
"markdownDescription": "Configure glob patterns to exclude from all IntelliSense features. Inherits all glob patterns from the `#files.exclude#` setting."
|
||||
},
|
||||
"tailwindCSS.classAttributes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
|
|
|
@ -31,6 +31,7 @@ import { languages as defaultLanguages } from 'tailwindcss-language-service/src/
|
|||
import isObject from 'tailwindcss-language-service/src/util/isObject'
|
||||
import { dedupe, equal } from 'tailwindcss-language-service/src/util/array'
|
||||
import namedColors from 'color-name'
|
||||
import minimatch from 'minimatch'
|
||||
|
||||
const colorNames = Object.keys(namedColors)
|
||||
|
||||
|
@ -82,6 +83,45 @@ function getUserLanguages(folder?: WorkspaceFolder): Record<string, string> {
|
|||
return isObject(langs) ? langs : {}
|
||||
}
|
||||
|
||||
function getExcludePatterns(folder: WorkspaceFolder): string[] {
|
||||
let globalExclude = Workspace.getConfiguration('files', folder).get('exclude')
|
||||
let exclude = Object.entries(globalExclude)
|
||||
.filter(([, value]) => value)
|
||||
.map(([key]) => key)
|
||||
|
||||
return [
|
||||
...exclude,
|
||||
...(<string[]>Workspace.getConfiguration('tailwindCSS', folder).get('files.exclude')),
|
||||
]
|
||||
}
|
||||
|
||||
function isExcluded(file: string, folder: WorkspaceFolder): boolean {
|
||||
let exclude = getExcludePatterns(folder)
|
||||
|
||||
for (let pattern of exclude) {
|
||||
if (minimatch(file, path.join(folder.uri.fsPath, pattern))) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
function mergeExcludes(settings, scope) {
|
||||
// merge `files.exclude` into `tailwindCSS.files.exclude`
|
||||
let globalExclude = Object.entries(Workspace.getConfiguration('files', scope).get('exclude'))
|
||||
.filter(([, value]) => value)
|
||||
.map(([key]) => key)
|
||||
|
||||
return {
|
||||
...settings,
|
||||
files: {
|
||||
...settings.files,
|
||||
exclude: [...globalExclude, ...settings.files.exclude],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export async function activate(context: ExtensionContext) {
|
||||
let module = context.asAbsolutePath(path.join('dist', 'server', 'index.js'))
|
||||
let prod = path.join('dist', 'server', 'tailwindServer.js')
|
||||
|
@ -108,8 +148,10 @@ export async function activate(context: ExtensionContext) {
|
|||
if (!folder) {
|
||||
return
|
||||
}
|
||||
folder = getOuterMostWorkspaceFolder(folder)
|
||||
bootWorkspaceClient(folder)
|
||||
if (!isExcluded(uri.fsPath, folder)) {
|
||||
folder = getOuterMostWorkspaceFolder(folder)
|
||||
bootWorkspaceClient(folder)
|
||||
}
|
||||
})
|
||||
|
||||
context.subscriptions.push(watcher)
|
||||
|
@ -180,7 +222,7 @@ export async function activate(context: ExtensionContext) {
|
|||
|
||||
let configuration = {
|
||||
editor: Workspace.getConfiguration('editor', folder),
|
||||
tailwindCSS: Workspace.getConfiguration('tailwindCSS', folder),
|
||||
tailwindCSS: mergeExcludes(Workspace.getConfiguration('tailwindCSS', folder), folder),
|
||||
}
|
||||
|
||||
let inspectPort = configuration.tailwindCSS.get('inspectPort')
|
||||
|
@ -309,7 +351,13 @@ export async function activate(context: ExtensionContext) {
|
|||
}
|
||||
}
|
||||
}
|
||||
return Workspace.getConfiguration(section, scope)
|
||||
let settings = Workspace.getConfiguration(section, scope)
|
||||
|
||||
if (section === 'tailwindCSS') {
|
||||
return mergeExcludes(settings, scope)
|
||||
}
|
||||
|
||||
return settings
|
||||
})
|
||||
},
|
||||
},
|
||||
|
@ -375,7 +423,7 @@ export async function activate(context: ExtensionContext) {
|
|||
|
||||
let [configFile] = await Workspace.findFiles(
|
||||
new RelativePattern(folder, `**/${CONFIG_FILE_GLOB}`),
|
||||
'**/node_modules/**',
|
||||
`{${getExcludePatterns(folder).join(',')}}`,
|
||||
1
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in New Issue