Skip to content

Commit

Permalink
Merge pull request #606 from krassowski/add-log-window
Browse files Browse the repository at this point in the history
Implement console log window messages, update lsp-ws-connection
  • Loading branch information
krassowski authored May 30, 2021
2 parents 739f3dd + 9b5c35f commit 22bf7b3
Show file tree
Hide file tree
Showing 15 changed files with 1,014 additions and 237 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,23 @@
- allow to set a priority for LSP server, allowing to choose which server to use when multiple servers are installed ([#588])
- add auto-detection of pyright server ([#587], thanks @yuntan)
- update from JupyterLab Classic to RetroLab ([#603])
- log server messages in user-accessible console ([#606])
- old emit-based API of lsp-ws-connection is new deprecated and will be removed in the next major version; please use `serverNotifications`, `clientNotifications`, `clientRequests` and `serverRequests` instead ([#606])

- bug fixes:

- workaround url-parse issue causing problems when using JupyterLab 3.0.15 ([#599])

- other changes:
- drop Node 10 (EOL 2 weeks ago) testing on CI, add Node 15 ([#587])
- update lsp-ws-connection dependencies ([#606])

[#586]: https://github.com/krassowski/jupyterlab-lsp/pull/586
[#587]: https://github.com/krassowski/jupyterlab-lsp/pull/587
[#588]: https://github.com/krassowski/jupyterlab-lsp/pull/588
[#599]: https://github.com/krassowski/jupyterlab-lsp/pull/599
[#602]: https://github.com/krassowski/jupyterlab-lsp/pull/602
[#606]: https://github.com/krassowski/jupyterlab-lsp/pull/606

### `jupyter-lsp 1.2.0` (2021-04-26)

Expand Down
6 changes: 4 additions & 2 deletions packages/jupyterlab-lsp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
"@krassowski/theme-material": "~2.1.0",
"@krassowski/theme-vscode": "~2.1.0",
"lodash.mergewith": "^4.6.1",
"lsp-ws-connection": "~0.5.1"
"lsp-ws-connection": "~0.6.0"
},
"devDependencies": {
"@babel/preset-env": "^7.4.3",
Expand All @@ -77,6 +77,7 @@
"@jupyterlab/docmanager": "^3.0.0",
"@jupyterlab/docregistry": "^3.0.0",
"@jupyterlab/fileeditor": "^3.0.0",
"@jupyterlab/logconsole": "^3.0.0",
"@jupyterlab/notebook": "^3.0.0",
"@jupyterlab/rendermime": "^3.0.0",
"@jupyterlab/services": "^6.0.0",
Expand All @@ -102,7 +103,8 @@
"react": "^17.0.1",
"rimraf": "^3.0.2",
"ts-jest": "^26.4.3",
"typescript": "~4.1.3"
"typescript": "~4.1.3",
"vscode-languageserver-protocol": "^3.16.0"
},
"peerDependencies": {
"@jupyterlab/application": "^3.0.0",
Expand Down
13 changes: 13 additions & 0 deletions packages/jupyterlab-lsp/schema/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,19 @@
"enum": ["debug", "log", "warn", "error"],
"default": "warn",
"description": "The verbosity of the console for debugging problems with this extension. Allowed values are: debug, log, warn, error."
},
"logAllCommunication": {
"title": "Log all LSP communication with the LSP servers",
"type": "boolean",
"default": false,
"description": "Whether all messages sent to and received from LSP servers should be logged into the console. To see these messages, set loggingLevel to debug or log. Note: Only messages handled by the new API will be shown."
},
"setTrace": {
"title": "Ask servers to send trace notifications",
"type": ["string", "null"],
"enum": ["off", "messages", "verbose", null],
"default": null,
"description": "Whether to ask server to send logs with execution trace (for debugging). To see these messages, set loggingLevel to debug or log. Accepted values are: \"off\", \"messages\", \"verbose\". Servers are allowed to ignore this request."
}
},
"jupyter.lab.shortcuts": []
Expand Down
75 changes: 75 additions & 0 deletions packages/jupyterlab-lsp/src/adapters/adapter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { JupyterFrontEnd } from '@jupyterlab/application';
import { Dialog, showDialog } from '@jupyterlab/apputils';
import { CodeEditor } from '@jupyterlab/codeeditor';
import { DocumentRegistry, IDocumentWidget } from '@jupyterlab/docregistry';
import { ILogPayload } from '@jupyterlab/logconsole';
import { nullTranslator, TranslationBundle } from '@jupyterlab/translation';
import { JSONObject } from '@lumino/coreutils';
import { Signal } from '@lumino/signaling';
Expand All @@ -21,6 +23,8 @@ import { IForeignContext, VirtualDocument } from '../virtual/document';
import { IVirtualEditor } from '../virtual/editor';

import IEditor = CodeEditor.IEditor;
import IButton = Dialog.IButton;
import createButton = Dialog.createButton;

export class StatusMessage {
/**
Expand Down Expand Up @@ -341,6 +345,77 @@ export abstract class WidgetAdapter<T extends IDocumentWidget> {
'have been initialized'
);
});

// Note: the logger extension behaves badly with non-default names
// as it changes the source to the active file afterwards anyways
const loggerSourceName = virtual_document.uri;
const logger = this.extension.user_console.getLogger(loggerSourceName);

data.connection.serverNotifications['$/logTrace'].connect(
(connection, message) => {
this.console.log(
data.connection.serverIdentifier,
'trace',
virtual_document.uri,
message
);
}
);

data.connection.serverNotifications['window/logMessage'].connect(
(connection, message) => {
this.console.log(
data.connection.serverIdentifier,
virtual_document.uri,
message
);
logger.log({
type: 'text',
data: connection.serverIdentifier + ': ' + message.message
} as ILogPayload);
}
);

data.connection.serverNotifications['window/showMessage'].connect(
(connection, message) => {
this.console.log(
data.connection.serverIdentifier,
virtual_document.uri,
message.message
);
void showDialog({
title: this.trans.__('Message from ') + connection.serverIdentifier,
body: message.message
});
}
);

data.connection.serverRequests['window/showMessageRequest'].setHandler(
async params => {
this.console.log(
data.connection.serverIdentifier,
virtual_document.uri,
params
);
const actionItems = params.actions;
const buttons = actionItems.map(action => {
return createButton({
label: action.title
});
});
const result = await showDialog<IButton>({
title:
this.trans.__('Message from ') + data.connection.serverIdentifier,
body: params.message,
buttons: buttons
});
const choice = buttons.indexOf(result.button);
if (choice === -1) {
return;
}
return actionItems[choice];
}
);
}

/**
Expand Down
Loading

0 comments on commit 22bf7b3

Please sign in to comment.