@master/css-language-server 2.0.0-beta.62

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/server.ts ADDED
@@ -0,0 +1,264 @@
1
+ import {
2
+ createConnection,
3
+ TextDocuments,
4
+ ProposedFeatures,
5
+ InitializeParams,
6
+ DidChangeConfigurationNotification,
7
+ CompletionItem,
8
+ TextDocumentPositionParams,
9
+ TextDocumentSyncKind,
10
+ InitializeResult,
11
+ DocumentColorParams,
12
+ ColorInformation,
13
+ ColorPresentationParams} from 'vscode-languageserver/node'
14
+
15
+ import { WorkspaceFolder } from 'vscode-languageserver'
16
+ import MasterCSS from '@master/css'
17
+
18
+ import * as minimatch from 'minimatch'
19
+
20
+ import { TextDocument } from 'vscode-languageserver-textdocument'
21
+ import { GetLastInstance, GetCompletionItem } from './completionProvider'
22
+ import { doHover } from './hoverProvider'
23
+ import { PositionCheck } from './masterCss'
24
+ import { GetDocumentColors, GetColorPresentation,GetColorRender } from './documentColorProvider'
25
+
26
+
27
+
28
+ const connection = createConnection(ProposedFeatures.all)
29
+ const documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument)
30
+
31
+ let hasConfigurationCapability = false
32
+ let hasWorkspaceFolderCapability = false
33
+ let hasDiagnosticRelatedInformationCapability = false
34
+ let settings: MasterCSSSettings
35
+
36
+ let MasterCSSObject: MasterCSS | undefined
37
+
38
+ // The example settings
39
+ interface MasterCSSSettings {
40
+ // eslint-disable-next-line @typescript-eslint/ban-types
41
+ languages: {},
42
+ classNameMatches: string[],
43
+ files: { exclude: string[] },
44
+ suggestions: boolean,
45
+ PreviewOnHovers: boolean,
46
+ PreviewColor: boolean
47
+ }
48
+ // The global settings, used when the `workspace/configuration` request is not supported by the client.
49
+ // Please note that this is not the case when using this server with the client provided in this example
50
+ // but could happen with other clients.
51
+ const defaultSettings: MasterCSSSettings = {
52
+ languages: [
53
+ 'html',
54
+ 'php',
55
+ 'javascript',
56
+ 'typescript',
57
+ 'javascriptreact',
58
+ 'typescriptreact',
59
+ 'vue',
60
+ 'svelte',
61
+ 'rust'
62
+ ],
63
+ classNameMatches: [
64
+ '(class(?:Name)?\\s?=\\s?)((?:"[^"]+")|(?:\'[^\']+\')|(?:`[^`]+`))',
65
+ '(class(?:Name)?={)([^}]*)}',
66
+ '(?:(\\$|(?:element\\.[^\\s.`]+)`)([^`]+)`)',
67
+ '(classList.(?:add|remove|replace|replace|toggle)\\()([^)]*)\\)'
68
+ ],
69
+ files: { exclude: ['**/.git/**', '**/node_modules/**', '**/.hg/**'] },
70
+ suggestions: true,
71
+ PreviewOnHovers: true,
72
+ PreviewColor: true
73
+ }
74
+ let globalSettings: MasterCSSSettings = defaultSettings
75
+
76
+ // Cache the settings of all open documents
77
+ const documentSettings: Map<string, Thenable<MasterCSSSettings>> = new Map()
78
+
79
+ connection.onDidChangeConfiguration(change => {
80
+ if (hasConfigurationCapability) {
81
+ // Reset all cached document settings
82
+ documentSettings.clear()
83
+ } else {
84
+ globalSettings = <MasterCSSSettings>(
85
+ (change.settings.languageServerExample || defaultSettings)
86
+ )
87
+ }
88
+
89
+ // Revalidate all open text documents
90
+ documents.all().forEach(validateTextDocument)
91
+ })
92
+
93
+ async function getDocumentSettings(resource: string): Promise<MasterCSSSettings> {
94
+ if (!hasConfigurationCapability) {
95
+ return Promise.resolve(globalSettings)
96
+ }
97
+ let result = documentSettings.get(resource)
98
+
99
+ if (!result) {
100
+ result = connection.workspace.getConfiguration({
101
+ scopeUri: resource,
102
+ section: 'masterCSS'
103
+ })
104
+ documentSettings.set(resource, result)
105
+ }
106
+
107
+ connection.workspace.getWorkspaceFolders()
108
+
109
+ const workspaceFolders = await connection.workspace.getWorkspaceFolders()
110
+ let root: WorkspaceFolder | undefined
111
+ if (workspaceFolders?.length === 1) {
112
+ root = workspaceFolders[0]
113
+ } else {
114
+ root = workspaceFolders?.find(x => resource.includes(x.uri))
115
+ }
116
+ if (root?.uri) {
117
+ try {
118
+ let userConfig = null
119
+ try {
120
+ const uri2path = await import('file-uri-to-path')
121
+ userConfig = await import(uri2path(root.uri.replace('%3A', ':') + '/master.css.js'))
122
+ } catch (_) { /* empty */ }
123
+ MasterCSSObject = new MasterCSS(userConfig)
124
+ } catch(_) { /* empty */ }
125
+ }
126
+ return result
127
+ }
128
+
129
+ // Only keep settings for open documents
130
+ documents.onDidClose(e => {
131
+ documentSettings.delete(e.document.uri)
132
+ })
133
+
134
+ // The content of a text document has changed. This event is emitted
135
+ // when the text document first opened or when its content has changed.
136
+ documents.onDidOpen(change => {
137
+ validateTextDocument(change.document)
138
+ })
139
+
140
+ async function validateTextDocument(textDocument: TextDocument): Promise<void> {
141
+ // In this simple example we get the settings for every validate run.
142
+ settings = await getDocumentSettings(textDocument.uri)
143
+
144
+ }
145
+
146
+ connection.onInitialize((params: InitializeParams) => {
147
+ const capabilities = params.capabilities
148
+
149
+
150
+ // Does the client support the `workspace/configuration` request?
151
+ // If not, we fall back using global settings.
152
+ hasConfigurationCapability = !!(
153
+ capabilities.workspace && !!capabilities.workspace.configuration
154
+ )
155
+ hasWorkspaceFolderCapability = !!(
156
+ capabilities.workspace && !!capabilities.workspace.workspaceFolders
157
+ )
158
+ hasDiagnosticRelatedInformationCapability = !!(
159
+ capabilities.textDocument &&
160
+ capabilities.textDocument.publishDiagnostics &&
161
+ capabilities.textDocument.publishDiagnostics.relatedInformation
162
+ )
163
+
164
+ const result: InitializeResult = {
165
+ capabilities: {
166
+ textDocumentSync: TextDocumentSyncKind.Incremental,
167
+
168
+ // Tell the client that this server supports code completion.
169
+ completionProvider: {
170
+ resolveProvider: true,
171
+ workDoneProgress: false,
172
+ triggerCharacters: [':', '@', '~']
173
+ },
174
+ colorProvider: {},
175
+ hoverProvider: true
176
+ }
177
+ }
178
+ if (hasWorkspaceFolderCapability) {
179
+ result.capabilities.workspace = {
180
+ workspaceFolders: {
181
+ supported: true
182
+ }
183
+ }
184
+ }
185
+ return result
186
+ })
187
+
188
+ connection.onInitialized(() => {
189
+ if (hasConfigurationCapability) {
190
+ // Register for all configuration changes.
191
+ connection.client.register(DidChangeConfigurationNotification.type, undefined)
192
+ }
193
+ })
194
+
195
+ connection.onCompletion(
196
+ (_textDocumentPosition: TextDocumentPositionParams): CompletionItem[] => {
197
+ if (settings.suggestions == true && CheckFilesExclude(_textDocumentPosition.textDocument.uri)) {
198
+
199
+ const inMasterCSS = PositionCheck(_textDocumentPosition.textDocument.uri, _textDocumentPosition.position, documents, settings.classNameMatches).IsMatch
200
+
201
+ const lastInstance = GetLastInstance(_textDocumentPosition, documents)
202
+ if (lastInstance.isInstance == true && inMasterCSS == true) {
203
+ return GetCompletionItem(lastInstance.lastKey, lastInstance.triggerKey, lastInstance.isStart, lastInstance.language, MasterCSSObject)
204
+ }
205
+ }
206
+ return []
207
+ }
208
+ )
209
+ connection.onCompletionResolve(
210
+ (item: CompletionItem): CompletionItem => {
211
+
212
+ return item
213
+ }
214
+ )
215
+
216
+
217
+ connection.onDocumentColor(
218
+ async (documentColor: DocumentColorParams): Promise<ColorInformation[]> => {
219
+ if (settings == null) {
220
+ return []
221
+ }
222
+ if (settings.PreviewColor == true && CheckFilesExclude(documentColor.textDocument.uri)) {
223
+ let colorInformation = await GetDocumentColors(documentColor, documents,settings.classNameMatches, MasterCSSObject)
224
+ colorInformation = colorInformation.concat(await GetColorRender(documentColor, documents))
225
+ return colorInformation
226
+ }
227
+ return []
228
+ })
229
+
230
+ connection.onColorPresentation((params: ColorPresentationParams) => {
231
+ if (settings.PreviewColor == true && CheckFilesExclude(params.textDocument.uri)) {
232
+ const colorRender = ['(?<=colors:\\s*{\\s*.*)([^}]*)}']
233
+ const isColorRender = PositionCheck(params.textDocument.uri, params.range.start, documents, colorRender)
234
+
235
+ return GetColorPresentation(params,isColorRender.IsMatch)
236
+ }
237
+ return []
238
+ })
239
+
240
+ connection.onHover(textDocumentPosition => {
241
+ if (settings.PreviewOnHovers == true && CheckFilesExclude(textDocumentPosition.textDocument.uri)) {
242
+ const HoverInstance = PositionCheck(textDocumentPosition.textDocument.uri, textDocumentPosition.position, documents, settings.classNameMatches)
243
+ if (HoverInstance.IsMatch) {
244
+ return doHover(HoverInstance.instance.instanceString, HoverInstance.instance.range, MasterCSSObject)
245
+ }
246
+ }
247
+ return null
248
+ })
249
+
250
+ function CheckFilesExclude(path: string): boolean {
251
+ for (const exclude of settings.files.exclude) {
252
+ if (minimatch(path, exclude)) {
253
+ return false
254
+ }
255
+ }
256
+ return true
257
+ }
258
+
259
+ // Make the text document manager listen on the connection
260
+ // for open, change and close text document events
261
+ documents.listen(connection)
262
+
263
+ // Listen on the connection
264
+ connection.listen()
@@ -0,0 +1,8 @@
1
+ import {
2
+ Color
3
+ } from 'vscode-languageserver/node';
4
+
5
+ export function hexToRgb(hex: string): Color {
6
+ const aRgbHex = hex.replace('#', '').match(/.{1,2}/g);
7
+ return { red: parseInt(aRgbHex?.[0] ?? '0', 16), green: parseInt(aRgbHex?.[1] ?? '0', 16), blue: parseInt(aRgbHex?.[2] ?? '0', 16), alpha: parseInt(aRgbHex?.[3] ?? 'FF', 16) }
8
+ }
@@ -0,0 +1 @@
1
+ export const instancePattern = /[^\s:]+:\w*\(?((?<!\\)["'`])((?:\\\1|(?:(?!\1))[\S\s])*)((?<!\\)\1)\)?|[^\s"'`]+/g
package/tsconfig.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2020",
4
+ "lib": ["es2020","DOM"],
5
+ "module": "commonjs",
6
+ "moduleResolution": "node",
7
+ "sourceMap": true,
8
+ "strict": true,
9
+ "outDir": "out",
10
+ "rootDir": "src"
11
+ },
12
+ "include": ["src"],
13
+ "exclude": ["node_modules", ".vscode-test"]
14
+ }