From 05d97cb291f840f7d92b6c08f7deb79e33bee218 Mon Sep 17 00:00:00 2001 From: Alex LaFroscia Date: Sun, 18 Apr 2021 02:19:33 -0400 Subject: [PATCH] feat: Support `workspace/didChangeConfiguration` event (#254) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * remove use of `any` type for initializers * log to root of ELS package This creates a debugging log file at the root of the ELS package, rather than inside the `lib` directory. The previous location was extremely difficult to find, since it’s alongside the compiled TypeScript output. An environment variable has also been added to more easily turn on the file logger. * perform logging to remote console if possible * respond to the `workspace/didChangeConfiguration` event Co-authored-by: Alex Kanunnikov --- .gitignore | 3 +++ src/server.ts | 37 ++++++++++++++++++++++++++----------- src/types.ts | 7 +++++++ src/utils/logger.ts | 23 +++++++++++++---------- 4 files changed, 49 insertions(+), 21 deletions(-) create mode 100644 src/types.ts diff --git a/.gitignore b/.gitignore index 1c2dfb4e..e1eb5e70 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ dist/ coverage inst/ .nyc_output + +# Debug Logging +debug.log diff --git a/src/server.ts b/src/server.ts index 9f51c35d..ef942e08 100644 --- a/src/server.ts +++ b/src/server.ts @@ -55,9 +55,10 @@ import { URI } from 'vscode-uri'; import { MatchResultType } from './utils/path-matcher'; import { FileChangeType } from 'vscode-languageserver/node'; import { debounce } from 'lodash'; +import { Config, Initializer } from './types'; export default class Server { - initializers: any[] = []; + initializers: Initializer[] = []; lazyInit = false; // Create a connection for the server. The connection defaults to Node's IPC as a transport, but // also supports stdio via command line flag @@ -117,6 +118,22 @@ export default class Server { } } + setConfiguration(config: Config) { + if (config.addons) { + this.projectRoots.setLocalAddons(config.addons); + } + + if (config.ignoredProjects) { + this.projectRoots.setIgnoredProjects(config.ignoredProjects); + } + + if (config.useBuiltinLinting === false) { + this.templateLinter.disable(); + } else if (config.useBuiltinLinting === true) { + this.templateLinter.enable(); + } + } + documentSymbolProviders: DocumentSymbolProvider[] = [new JSDocumentSymbolProvider(), new HBSDocumentSymbolProvider()]; templateCompletionProvider: TemplateCompletionProvider = new TemplateCompletionProvider(this); @@ -129,7 +146,7 @@ export default class Server { referenceProvider: ReferenceProvider = new ReferenceProvider(this); codeActionProvider: CodeActionProvider = new CodeActionProvider(this); executeInitializers() { - this.initializers.forEach((cb: any) => cb()); + this.initializers.forEach((cb) => cb()); this.initializers = []; } private onInitialized() { @@ -137,15 +154,8 @@ export default class Server { this.connection.workspace.onDidChangeWorkspaceFolders(this.onDidChangeWorkspaceFolders.bind(this)); } - this.executors['els.setConfig'] = async (_, __, [config]: [{ local: { addons: string[]; ignoredProjects: string[]; useBuiltinLinting: boolean } }]) => { - this.projectRoots.setLocalAddons(config.local.addons); - this.projectRoots.setIgnoredProjects(config.local.ignoredProjects); - - if (config.local.useBuiltinLinting === false) { - this.templateLinter.disable(); - } else if (config.local.useBuiltinLinting === true) { - this.templateLinter.enable(); - } + this.executors['els.setConfig'] = async (_, __, [config]: [{ local: Config }]) => { + this.setConfiguration(config.local); if (this.lazyInit) { this.executeInitializers(); @@ -280,6 +290,7 @@ export default class Server { this.documents.onDidChangeContent(this.onDidChangeContent); this.documents.onDidOpen(this.onDidChangeContent); this.connection.onDidChangeWatchedFiles(this.onDidChangeWatchedFiles.bind(this)); + this.connection.onDidChangeConfiguration(this.onDidChangeConfiguration.bind(this)); this.connection.onDocumentSymbol(this.onDocumentSymbol.bind(this)); this.connection.onDefinition(this.definitionProvider.handler); this.connection.onCompletion(this.onCompletion.bind(this)); @@ -529,6 +540,10 @@ export default class Server { // const Deleted = 3; } + private onDidChangeConfiguration({ settings }: { settings: Config }) { + this.setConfiguration(settings); + } + private async onReference(params: ReferenceParams): Promise { return await this.referenceProvider.provideReferences(params); } diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 00000000..96468424 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,7 @@ +export type Initializer = () => void; + +export interface Config { + addons: string[]; + ignoredProjects: string[]; + useBuiltinLinting: boolean; +} diff --git a/src/utils/logger.ts b/src/utils/logger.ts index 8b51e71a..c17deee9 100644 --- a/src/utils/logger.ts +++ b/src/utils/logger.ts @@ -1,10 +1,13 @@ import * as fs from 'fs'; import * as util from 'util'; +import { resolve } from 'path'; import { RemoteConsole } from 'vscode-languageserver/node'; -const debug = false; -const log_file = debug ? fs.createWriteStream(__dirname + '/debug.log', { flags: 'w' }) : null; +// Log debugging to the ELS package root, if possible +const debug = process.env.ELS_DEBUG || false; +const log_file = debug ? fs.createWriteStream(resolve(__dirname, '../../debug.log'), { flags: 'w' }) : null; + let remoteConsole: RemoteConsole | null = null; export function logError(err: any) { @@ -43,16 +46,16 @@ export function safeStringify(obj: unknown, indent = 2) { return retVal; } -export function log(...args: any[]) { - if (!debug || !log_file) { - return; +export function log(...args: unknown[]) { + const output = args.map((a) => safeStringify(a)).join(' '); + + if (remoteConsole) { + remoteConsole.log(output); } - const output = args - .map((a: any) => { - return safeStringify(a); - }) - .join(' '); + if (!log_file) { + return; + } log_file.write('----------------------------------------' + '\r\n'); log_file.write(util.format(output) + '\r\n');