From 8eaa5c9326deaae3485ae3aa7015bb2d61468ec9 Mon Sep 17 00:00:00 2001 From: Brad Cornes Date: Sat, 9 May 2020 17:24:56 +0100 Subject: [PATCH] add notification handlers --- package-lock.json | 6 ++++ package.json | 1 + src/extension.ts | 4 ++- src/lib/emitter.ts | 50 +++++++++++++++++++++++++++ src/lib/registerConfigErrorHandler.ts | 35 +++++++++---------- src/lsp/notifications.ts | 15 ++++++++ 6 files changed, 91 insertions(+), 20 deletions(-) create mode 100644 src/lib/emitter.ts create mode 100644 src/lsp/notifications.ts diff --git a/package-lock.json b/package-lock.json index d966ffc..d3461d1 100755 --- a/package-lock.json +++ b/package-lock.json @@ -4910,6 +4910,12 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, + "mitt": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.2.0.tgz", + "integrity": "sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==", + "dev": true + }, "mixin-deep": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", diff --git a/package.json b/package.json index 2e23359..69d62d9 100755 --- a/package.json +++ b/package.json @@ -91,6 +91,7 @@ "import-from": "^3.0.0", "jest": "^25.5.4", "line-column": "^1.0.2", + "mitt": "^1.2.0", "mkdirp": "^1.0.3", "pkg-up": "^3.1.0", "postcss": "^7.0.27", diff --git a/src/extension.ts b/src/extension.ts index 2497372..be1fe47 100755 --- a/src/extension.ts +++ b/src/extension.ts @@ -21,6 +21,7 @@ import { registerConfigErrorHandler } from './lib/registerConfigErrorHandler' import { DEFAULT_LANGUAGES } from './lib/languages' import isObject from './util/isObject' import { dedupe, equal } from './util/array' +import { createEmitter } from './lib/emitter' const CLIENT_ID = 'tailwindcss-intellisense' const CLIENT_NAME = 'Tailwind CSS IntelliSense' @@ -147,7 +148,8 @@ export function activate(context: ExtensionContext) { ) client.onReady().then(() => { - registerConfigErrorHandler(client) + let emitter = createEmitter(client) + registerConfigErrorHandler(emitter) }) client.start() diff --git a/src/lib/emitter.ts b/src/lib/emitter.ts new file mode 100644 index 0000000..d177c2c --- /dev/null +++ b/src/lib/emitter.ts @@ -0,0 +1,50 @@ +import mitt from 'mitt' +import { LanguageClient } from 'vscode-languageclient' +import crypto from 'crypto' + +export interface NotificationEmitter { + on: (name: string, handler: (args: any) => void) => void + off: (name: string, handler: (args: any) => void) => void + emit: (name: string, args: any) => Promise +} + +export function createEmitter(client: LanguageClient): NotificationEmitter { + const emitter = mitt() + const registered: string[] = [] + + const on = (name: string, handler: (args: any) => void) => { + if (!registered.includes(name)) { + registered.push(name) + client.onNotification(`tailwindcss/${name}`, (args) => + emitter.emit(name, args) + ) + } + emitter.on(name, handler) + } + + const off = (name: string, handler: (args: any) => void) => { + emitter.off(name, handler) + } + + const emit = (name: string, params: any) => { + return new Promise((resolve, _reject) => { + const id = crypto.randomBytes(16).toString('hex') + on(`${name}Response`, (result) => { + const { _id, ...rest } = result + if (_id === id) { + resolve(rest) + } + }) + client.sendNotification(`tailwindcss/${name}`, { + _id: id, + ...params, + }) + }) + } + + return { + on, + off, + emit, + } +} diff --git a/src/lib/registerConfigErrorHandler.ts b/src/lib/registerConfigErrorHandler.ts index 819458e..80ee6a5 100644 --- a/src/lib/registerConfigErrorHandler.ts +++ b/src/lib/registerConfigErrorHandler.ts @@ -1,23 +1,20 @@ -import { LanguageClient } from 'vscode-languageclient' import { window, Uri, Range, Position } from 'vscode' +import { NotificationEmitter } from './emitter' -export function registerConfigErrorHandler(client: LanguageClient) { - client.onNotification( - 'tailwindcss/configError', - async ({ message, file, line }) => { - const actions: string[] = file ? ['View'] : [] - const action = await window.showErrorMessage( - `Tailwind CSS: ${message}`, - ...actions - ) - if (action === 'View') { - window.showTextDocument(Uri.file(file), { - selection: new Range( - new Position(line - 1, 0), - new Position(line - 1, 0) - ), - }) - } +export function registerConfigErrorHandler(emitter: NotificationEmitter) { + emitter.on('configError', async ({ message, file, line }) => { + const actions: string[] = file ? ['View'] : [] + const action = await window.showErrorMessage( + `Tailwind CSS: ${message}`, + ...actions + ) + if (action === 'View') { + window.showTextDocument(Uri.file(file), { + selection: new Range( + new Position(line - 1, 0), + new Position(line - 1, 0) + ), + }) } - ) + }) } diff --git a/src/lsp/notifications.ts b/src/lsp/notifications.ts new file mode 100644 index 0000000..bb4e60d --- /dev/null +++ b/src/lsp/notifications.ts @@ -0,0 +1,15 @@ +import { Connection } from 'vscode-languageserver' + +export function onMessage( + connection: Connection, + name: string, + handler: (params: any) => any +): void { + connection.onNotification(`tailwindcss/${name}`, async (params: any) => { + const { _id, ...rest } = params + connection.sendNotification(`tailwindcss/${name}Response`, { + _id, + ...(await handler(rest)), + }) + }) +}