{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Extend jupyterlab-lsp and jupyter-lsp" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### jupyterlab-lsp\n", "\n", "> At present, `jupyterlab-lsp` is still in very early development, and does not\n", "> expose any runtime extension points. The [roadmap](./Roadmap.ipynb) lists\n", "> several potential points of extension, but will require some refactoring to\n", "> achieve." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### jupyter-lsp\n", "\n", "#### Language Server Specs\n", "\n", "Language Server Specs can be [configured](./Configuring.ipynb) by Jupyter users,\n", "or distributed by third parties as python or JSON files. Since we'd like to see\n", "as many Language Servers work out of the box as possible, consider\n", "[contributing a spec](./Contributing.ipynb#specs), if it works well for you!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Message Listeners\n", "\n", "Message listeners may choose to receive LSP messages immediately after being\n", "received from the client (e.g. `jupyterlab-lsp`) or a language server. All\n", "listeners of a message are scheduled concurrently, and the message is passed\n", "along **once all listeners return** (or fail). This allows listeners to, for\n", "example, modify files on disk before the language server reads them.\n", "\n", "If a listener is going to perform an expensive activity that _shouldn't_ block\n", "delivery of a message, a non-blocking technique like\n", "[IOLoop.add_callback][add_callback] and/or a\n", "[queue](https://www.tornadoweb.org/en/stable/queues.html) should be used.\n", "\n", "[add_callback]:\n", " https://www.tornadoweb.org/en/stable/ioloop.html#tornado.ioloop.IOLoop.add_callback" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### Add a Listener with `entry_points`\n", "\n", "Listeners can be added via [entry_points][] by a package installed in the same\n", "environment as `notebook`:\n", "\n", "```toml\n", "## setup.cfg\n", "\n", "[options.entry_points]\n", "jupyter_lsp_listener_all_v1 =\n", " some-unique-name = some.module:some_function\n", "jupyter_lsp_listener_client_v1 =\n", " some-other-unique-name = some.module:some_other_function\n", "jupyter_lsp_listener_server_v1 =\n", " yet-another-unique-name = some.module:yet_another_function\n", "```\n", "\n", "At present, the entry point names generally have no impact on functionality\n", "aside from logging in the event of an error on import.\n", "\n", "[entry_points]: https://packaging.python.org/specifications/entry-points/" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### Add a Listener with Jupyter Configuration\n", "\n", "Listeners can be added via `traitlets` configuration, e.g.\n", "\n", "```yaml\n", "## jupyter_notebook_config.jsons\n", "{\n", " 'LanguageServerManager':\n", " {\n", " 'all_listeners': ['some.module.some_function'],\n", " 'client_listeners': ['some.module.some_other_function'],\n", " 'server_listeners': ['some.module.yet_another_function'],\n", " },\n", "}\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### Add a listener with the Python API\n", "\n", "`lsp_message_listener` can be used as a decorator, accessed as part of a\n", "`serverextension`.\n", "\n", "This listener receives _all_ messages from the client and server, and prints\n", "them out.\n", "\n", "```python\n", "from jupyter_lsp import lsp_message_listener\n", "\n", "def load_jupyter_server_extension(nbapp):\n", "\n", " @lsp_message_listener(\"all\")\n", " async def my_listener(scope, message, language_server, manager):\n", " print(\"received a {} {} message from {}\".format(\n", " scope, message[\"method\"], language_server\n", " ))\n", "```\n", "\n", "`scope` is one of `client`, `server` or `all`, and is required." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "##### Listener options\n", "\n", "Fine-grained controls are available as part of the Python API. Pass these as\n", "named arguments to `lsp_message_listener`.\n", "\n", "- `language_server`: a regular expression of language servers\n", "- `method`: a regular expression of LSP JSON-RPC method names" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.6" } }, "nbformat": 4, "nbformat_minor": 4 }