@jupyter-lsp/jupyterlab-lsp
Version:
Language Server Protocol integration for JupyterLab
186 lines • 5.73 kB
JavaScript
import '../../style/console.css';
import { ISettingRegistry } from '@jupyterlab/settingregistry';
import { Signal } from '@lumino/signaling';
import { ILSPLogConsole, PLUGIN_ID } from '../tokens';
function toString(args) {
return args
.map(arg => {
let textual;
if (typeof arg === 'string') {
return arg;
}
try {
textual = JSON.stringify({ k: arg }).slice(5, -1);
}
catch {
textual = '' + arg;
}
return '<span class="lsp-code">' + textual + '</span>';
})
.join(' ');
}
class FloatingConsole {
constructor(scope = ['LSP'], element = null) {
if (element) {
this.element = element;
}
else {
this.element = document.createElement('ul');
this.element.className = 'lsp-floating-console';
document.body.appendChild(this.element);
}
}
bindThis() {
return this;
}
dispose() {
this.element.remove();
}
append(text, kind = 'log') {
let entry = document.createElement('li');
entry.innerHTML = '<span class="lsp-kind">' + kind + '</span>' + text;
this.element.appendChild(entry);
this.element.scrollTop = this.element.scrollHeight;
}
debug(...args) {
this.append(toString(args), 'debug');
}
log(...args) {
this.append(toString(args), 'log');
}
warn(...args) {
this.append(toString(args), 'warn');
}
error(...args) {
this.append(toString(args), 'error');
}
}
/**
* Used both as a console implementation, and as a dummy ILSPLogConsole
*/
export class BrowserConsole {
constructor() {
this.debug = window.console.debug.bind(window.console);
this.log = window.console.log.bind(window.console);
this.warn = window.console.warn.bind(window.console);
this.error = window.console.error.bind(window.console);
}
dispose() {
return;
}
scope(scope) {
return this;
}
bindThis() {
return window.console;
}
}
class ConsoleWrapper {
constructor(scope = ['LSP'], singleton) {
this.breadcrumbs = scope;
this._scope = this.breadcrumbs.join('.') + ':';
this.singleton = singleton;
this.singleton.changed.connect(this._rebindFunctions.bind(this));
this._rebindFunctions();
}
/**
* Re-binding directly to the underlying functions allows to get nice
* location (file:line) of the actual call rather than of this wrapper
* when using with the browser implementation.
*/
_rebindFunctions() {
const noOp = () => {
// do nothing
};
const bindArg = this.implementation.bindThis();
if (this.verbosity === 'debug') {
this.debug = this.implementation.debug.bind(bindArg, this._scope);
}
else {
this.debug = noOp;
}
if (this.verbosity === 'debug' || this.verbosity === 'log') {
this.log = this.implementation.log.bind(bindArg, this._scope);
}
else {
this.log = noOp;
}
if (this.verbosity === 'debug' ||
this.verbosity === 'log' ||
this.verbosity === 'warn') {
this.warn = this.implementation.warn.bind(bindArg, this._scope);
}
else {
this.warn = noOp;
}
this.error = this.implementation.error.bind(bindArg, this._scope);
}
get verbosity() {
return this.singleton.verbosity;
}
get implementation() {
return this.singleton.implementation;
}
debug(...args) {
return this.implementation.debug(this._scope, ...args);
}
log(...args) {
return this.implementation.log(this._scope, ...args);
}
warn(...args) {
return this.implementation.warn(this._scope, ...args);
}
error(...args) {
return this.implementation.error(this._scope, ...args);
}
scope(scope) {
return new ConsoleWrapper([...this.breadcrumbs, scope], this.singleton);
}
}
class ConsoleSingleton {
constructor(settingRegistry) {
// until loaded log everything, to browser console
this.verbosity = 'debug';
this.implementation = new BrowserConsole();
this.changed = new Signal(this);
settingRegistry
.load(PLUGIN_ID + ':plugin')
.then(settings => {
this.updateSettings(settings);
settings.changed.connect(() => {
this.updateSettings(settings);
});
})
.catch(console.warn);
}
updateSettings(settings) {
const composite = settings.composite;
const kind = composite.loggingConsole;
if (this.implementation) {
this.implementation.dispose();
}
if (kind === 'browser') {
this.implementation = new BrowserConsole();
}
else if (kind === 'floating') {
this.implementation = new FloatingConsole();
}
else {
console.warn('Unknown console type', kind, 'falling back to browser console');
this.implementation = new BrowserConsole();
}
this.verbosity = composite.loggingLevel;
this.changed.emit();
}
}
export const LOG_CONSOLE = {
id: PLUGIN_ID + ':ILSPLogConsole',
requires: [ISettingRegistry],
activate: (app, settingRegistry) => {
const singleton = new ConsoleSingleton(settingRegistry);
return new ConsoleWrapper(['LSP'], singleton);
},
provides: ILSPLogConsole,
autoStart: true
};
//# sourceMappingURL=console.js.map