Jupyter[Lab] Language Server Protocol#
This is the documentation for:
Both are managed on GitHub, where you can find the issue tracker.
Installation#
Please Read This First#
Delivering LSP features to your JupyterLab requires three pieces:
1. jupyter-lsp
#
runs in your
jupyter_server
application on your server to handle requests from the browser to language serversto run, you need:
python >=3.8,<3.11.0a0
jupyter_server >=1.1.2
2. jupyterlab-lsp
#
runs in your browser, as an extension to JupyterLab
to install it, you need:
jupyterlab >=4.0.5,<5.0.0a0
3. Language Servers#
run on your server
probably in another language runtime than python
some can be automatically detected if installed
others also need to be configured
Clean installation#
The approaches demonstrated below will ensure that correct versions of Python,
JupyterLab and extensions are installed, and are generally recommended for
novice users, or users who are not familiar with the Python ecosystem. However,
if you feel proficient with using Python package managers such as pip
and
conda
you may prefer to follow the custom installation
guide instead, which allows to install the packages in an existing environment.
conda (minimal python)#
When installing from conda-forge, the jupyter-lsp-python
bundle includes both
the server extension (jupyter-lsp
) and pyls
(a third-party server also known
as python-language-server
). You can swap jupyter-lsp-python
with another
pre-made bundle, jupyter-lsp-r
to get get the same server extension but with
r-languageserver
instead. Alternatively, you can install a language server of
your choice manually (see further steps).
conda create -c conda-forge -n lsp 'python >=3.8,<3.11.0a0' 'jupyterlab=4.0.5' 'jupyterlab-lsp=5.0.0-beta.0' 'jupyter-lsp-python=2.2.0'
conda activate lsp
Then run
jupyter lab
Your browser should open to your local server.
docker (data science)#
This approach is based roughly on the Jupyter docker-stacks documentation, which should be consulted for more about connecting volumes, passwords, and other advanced features:
Note: docker instructions were not updated for JupyterLab 3.0 and extension 3.0. Please consider submitting a PR to fix it.
Dockerfile
#
# This already contains the python, r, julia, latex, and nodejs runtimes
FROM jupyter/datascience-notebook@sha256:73a577b006b496e1a1c02f5be432f4aab969c456881c4789e0df77c89a0a60c2
RUN conda install --quiet --yes --freeze-installed -c conda-forge \
'python-language-server' \
'jupyterlab=4.0.5' \
'r-languageserver' \
'texlab' \
'chktex' \
'jupyter-lsp=2.2.0' \
&& jupyter labextension install --no-build \
'@jupyter-lsp/jupyterlab-lsp@5.0.0-beta.0' \
&& jupyter lab build --dev-build=False --minimize=True \
&& conda clean --all -f -y \
&& rm -rf \
$CONDA_DIR/share/jupyter/lab/staging \
/home/$NB_USER/.cache/yarn \
&& fix-permissions $CONDA_DIR \
&& fix-permissions /home/$NB_USER
docker-compose.yml
#
version: '2'
services:
lsp-lab:
build: .
ports:
- '18888:8888'
Build and Start#
docker-compose up
You should now be able to access http://localhost:18888/lab
, using the token
provided in the log.
Custom installation#
Get a working JupyterLab environment#
Refer to the official JupyterLab Installation Documentation for your installation approach.
pip |
conda |
pipenv |
poetry |
|
---|---|---|---|---|
|
|
|
*
PRs welcome!
Verify your lab works:
jupyter lab --version
jupyter lab
Install Jupyter[Lab] LSP#
conda#
conda install jupyterlab-lsp=5.0.0-beta.0
pip#
pip install jupyterlab-lsp==5.0.0-beta.0
Next step: Language Servers#
Now that you have jupyterlab-lsp
, jupyter-lsp
and all of their dependencies,
you’ll need some language servers. See:
Language Servers that will be found automatically once installed
configuring
jupyter-lsp
for more control over which servers to load
Language servers#
By default jupyter-lsp
does not come with any language servers preinstalled.
However, we will try to use them if they are installed and we know about them
(i.e. someone contributed a full specification).
You can disable auto-detection by configuring autodetect
You can add another language server for languages that are not listed on this page:
using a minimal JSON or Python configuration file (good for experimenting or configuring a niche server), or
contributing a full specification (to enable better integration and help other users of the same language)
The existing language servers are listed on the official list and on the community-curated list.
For the language servers in the tables below, use one of the suggested package
managers to install them: these implementations are tested to work with
jupyter-lsp
.
Servers tested with Notebooks#
While most servers should work with notebooks and standalone files, some require
additional adjustments. The following language servers are tested against
jupyterlab-lsp
and any issues when using them in notebooks will be
prioritised.
If you choose to install multiple language servers for the same language, the
one with the highest priority
(which can be set in the Advanced Settings
Editor) will be used.
Languages | Implementation | Installation |
---|---|---|
python |
jedi-language-server |
|
julia |
julia-language-server |
|
python |
pylsp |
|
r |
r-languageserver |
|
robotframework |
robotframework_ls |
|
If you plan to add a custom language server for the use with notebooks, please note that a complete set of information should be provided by the kernel, as described in making custom servers work with notebooks.
Servers tested with file editor#
Servers requiring Node.js#
These servers have mostly been tested with file editors.
Languages | Implementation | Installation |
---|---|---|
bash sh |
bash-language-server |
|
dockerfile |
dockerfile-language-server-nodejs |
|
python |
pyright |
|
sql |
sql-language-server |
|
javascript jsx typescript typescript-jsx typescriptreact javascriptreact |
typescript-language-server |
|
markdown ipythongfm gfm |
unified-language-server |
|
css less scss |
vscode-css-languageserver-bin |
|
html |
vscode-html-languageserver-bin |
|
json |
vscode-json-languageserver-bin |
|
yaml |
yaml-language-server |
|
NodeJS (preferably even-numbered an Active or Maintenance Long Term Support release) is a prerequisite for installation of any of the above language servers; you can get it with:
conda install --channel conda-forge nodejs
# or one of the following, as an administrator
choco install nodejs # Windows with Chocolatey
sudo apt-get install nodejs # Debian/Ubuntu
sudo brew install nodejs # MacOS with Homebrew
sudo dnf install nodejs # Fedora
sudo yum install nodejs # RHEL/CentOS
Example: getting all the Node.js-based language servers#
A number of language servers are built on the
reference implementation,
powered by Node.js. The most reliable place to install these is in a
node_modules
in the directory where you launch jupyter lab
.
For example, to install all the servers which are tested as part of
jupyterlab-lsp
:
jlpm add --dev \
bash-language-server \
dockerfile-language-server-nodejs \
pyright \
sql-language-server \
typescript-language-server \
unified-language-server \
vscode-css-languageserver-bin \
vscode-html-languageserver-bin \
vscode-json-languageserver-bin \
yaml-language-server
This will create (or add to):
package.json
(check this in!)yarn.lock
(check this in!)node_modules/
(add to your VCS ignore file)
If you wish to install these someplace else, you may need to specify where you install them with extra_node_roots.
Standalone servers#
These servers have been mostly tested with file editor.
Languages | Implementation | Installation |
---|---|---|
tex latex |
texlab |
|
Example: Getting a \(\LaTeX\) stack#
conda install --channel conda-forge tectonic texlab chktex
This will install:
tectonic
, a cross-platform \(\LaTeX\) processing toolnote, it will download a large number of packages when first executed
texlab
, a Language Server for.tex
files that supports completion and reference navigationchktex
, a.tex
style checker
Community-supported servers#
Servers and extensions listed below are not included in the testing suite of
jupyterlab-lsp
; the support may be provided by community members or a
third-party:
Languages |
Implementation |
Comment |
---|---|---|
Spark SQL |
||
GraphQL, SPARQL, Turtle |
||
JSON |
(1) |
|
YAML |
(1) |
|
Scala |
(2) |
(1) convenience wrappers for installation with
pip
, require Node.js.(2)
metals
is not currently auto-detected, but can be configured as demonstrated in the configuration example.
Troubleshooting#
r-languageserver
Rscript not found. Please ensure that RScript executable is in the PATH; this should happen automatically when using Linux, Mac OS or Conda, but will require manual configuration when using the default R installer on Windows. For more details please consult documentation: https://cran.r-project.org/bin/windows/base/rw-FAQ.html#Rcmd-is-not-found-in-my-PATH_0021 If Rscript is already in the PATH, you can check whether the language server package is properly installed with: Rscript -e "cat(system.file(package='languageserver'))" which should return the path to the installed package.
texlab
texlab not found. Please ensure that texlab executable is in the PATH; this should happen automatically when installing texlab from Conda, but may require manual configuration of PATH environment variable if you compiled texlab from source. You can ensure check if texlab is in the PATH, by running: which texlab which should return the path to the executable (if found).
Configuring backend#
Configuration Files#
Like the Jupyter Notebook server, JupyterHub, and other Jupyter interactive
computing tools, jupyter-lsp
can be configured via Python or JSON
files in well-known locations. You can find out where to put
them on your system with:
jupyter --paths
They will be merged from bottom to top, and the directory where you launch your
notebook
or lab
server wins, making it easy to check in to version control.
Configuration Options#
language_servers#
jupyter-lsp
does not come with any Language Servers! However, we will try to
use known language servers if they are installed
and we know about them. You can disable auto-detection behavior by configuring
autodetect.
If you did not find an implementation for the language server you need on the list of known language servers, continue reading!
Please consider contributing your language server spec to
jupyter-lsp
!
The absolute minimum language server spec requires:
argv
, a list of shell tokens to launch the server instdio
mode (as opposed totcp
),shell tokens are arrays of strings representing command line commands with arguments, for example
ls -l
is represented as["ls", "-l"]
whilemkdir "new directory"
should be split into["mkdir", "new directory"]
; If you have Python installed, you can useshlex.split("your command")
to get such an array.
the
languages
which the language server will respond to, andthe schema
version
of the spec (currently2
)mime_types
by which the notebooks and files will be matched to the language server:for notebooks the MIME type is derived from
language_info
/mimetype
element of kernel_info response (with fallback on to cell metadata if missing from kernel response)for files the implementation is frontend-specific; in JupyterLab the MIME type is obtained from: a) the code editor MIME type registry, which is by default using the CodeMirror mode as for JupyterLab 3.x, or if no specific MIME type is found there, then b) from the
DocumentRegistry
file type by matching thecontentsModel
against the registered file types usinggetFileTypeForModel()
method (if multiple MIME types are present, the first one will be used).
requires_documents_on_disk
should befalse
for all new specifications, as any code paths requiring documents on disks should be fixed in the LSP servers rather than masked by using the.virtual_documents
workaround.
# ./jupyter_server_config.json ---------- unique! -----------
# | |
# or e.g. V V
# $PREFIX/etc/jupyter/jupyter_server_config.d/a-language-server-implementation.json
{
"LanguageServerManager": {
"language_servers": {
"a-language-server-implementation": {
"version": 2,
"argv": ["/absolute/path/to/a-language-server", "--stdio"],
"languages": ["a-language"],
"mime_types": ["text/language", "text/x-language"],
"display_name": "My LSP server"
}
}
}
}
The documentation of display_name
along many other properties is available in
the schema. Please note that some of the properties defined in the schema
are intended for future use: we would like to use them to enrich the user
experience but we prioritized other features for now. We welcome any help in
creating the user interface making use of these properties.
More complex configurations that can’t be hard-coded may benefit from the python approach:
# jupyter_server_config.py
import shutil
# c is a magic, lazy variable
c.LanguageServerManager.language_servers = {
"a-language-server-implementation": {
# if installed as a binary
"argv": [shutil.which("a-language-server")],
"languages": ["a-language"],
"version": 2,
"mime_types": ["text/a-language"],
"display_name": "A language server"
},
"another-language-implementation": {
# if run like a script
"argv": [shutil.which("another-language-interpreter"), "another-language-server"],
"languages": ["another-language"],
"version": 2,
"mime_types": ["text/another-language"],
"display_name": "Another language server"
}
}
nodejs#
default:
None
An absolute path to your nodejs
executable. If None
, nodejs
will be
detected in a number of well-known places.
autodetect#
default:
True
If True
, jupyter-lsp
will look for all
known language servers. User-configured
language_servers
of the same implementation will be preferred over
autodetect
ed ones.
node_roots#
default:
[]
Absolute paths to search for directories named node_modules
, such as
nodejs
-backed language servers. The order is, roughly:
the folder where
notebook
orlab
was launchedthe JupyterLab
staging
folderwherever
conda
puts global node moduleswherever some other conventions put it
extra_node_roots#
default:
[]
Additional places jupyter-lsp
will look for node_modules
. These will be
checked before node_roots
, and should not contain the trailing
node_modules
.
virtual_documents_dir#
default: os.getenv(“JP_LSP_VIRTUAL_DIR”, “.virtual_documents”)
Path (relative to the content manager root directory) where a transient copy of the virtual documents should be written allowing LSP servers to access the file using operating system’s file system APIs if they need so (which is discouraged).
Its default value can be set with JP_LSP_VIRTUAL_DIR
environment variable. The
fallback value is .virtual_documents
.
Python entry_points
#
pip
-installable packages in the same environment as the Jupyter server can be
automatically detected as providing language_servers. These
are a little more involved, but also more powerful: see more in
Contributing. Servers configured this way are loaded
before those defined in configuration files, so that a
user can fine-tune their available servers.
Making Custom Servers Work With Notebooks#
To enable integration of language servers with Jupyter notebooks this extensions
assumes that the language_info
section of kernel_info_reply
is complete and properly returned by the Kernel. In particular the following
elements are required:
File extension: many language servers only handle files with specific file extensions and refuse to operate if not provided with such; the file extension of a native script for a given language (this is other than
.ipynb
), derived fromfile_extension
field oflanguage_info
, will be added to the name of the notebook when communicating with the language server to satisfy the file extension check.MIME type: matching of notebooks to servers is based on the MIME types declared in server specification files and
mimetype
field oflanguage_info
. If kernel fails to provide any MIME type, connecting the language server will not be possible; if multiple MIME types are in use, any would work well for this extension as long as you also include it in themime_types
list of language server specification.
Example: Scala Language Server (metals) integration#
Step 1: Get a Scala-based kernel installed.
2 possible options: Almond kernel or the Spark magic kernel.
Almond kernel install:
$ curl -Lo coursier https://git.io/coursier-cli
$ chmod +x coursier
$ ./coursier launch --fork almond -- --install
$ rm -f coursier
Spark Magic kernel:
pip install sparkmagic
Now, install the spark kernel:
jupyter-kernelspec install sparkmagic/kernels/sparkkernel
Step 2: Install metals server in the working directory:
Metals has a coursier based installation.
curl -Lo coursier https://git.io/coursier-cli && chmod +x coursier
./coursier bootstrap org.scalameta:metals_2.12:0.7.0 --force-fetch -o metals -f
(Might need to use the --force-fetch
flag if you are getting dependency
issues.)
Step 3: Configure the metals server in jupyterlab-lsp. Enter the following
in the jupyter/jupyter_server_config.d/metals-ls.json
(in one of the jupyter
configuration directories):
{
"LanguageServerManager": {
"language_servers": {
"metals": {
"version": 2,
"argv": ["<$path_to_metals_server(eg:/Users/skakker/projects/jupyterlab-lsp/metals)>"],
"languages": ["scala"],
"mime_types": ["text/x-scala"]
}
}
}
}
You are good to go now! Just start jupyter lab
and create a notebook with
either the Spark or the Scala kernel and the metals server should automatically
initialise (the status indicator should show “Fully initialized”).
Contributing#
jupyter-lsp
and jupyterlab-lsp
are open source software, and
all contributions conforming to good sense, good taste, and the
Jupyter Code of Conduct are welcome, and will be reviewed
by the contributors, time-permitting.
You can contribute to the project through:
creating language server specs
you can publish them yourself (it might be a single file)…
or advocate for adding your spec to the github repository and its various distributions
these are great first issues, as you might not need to know any python or javascript
proposing parts of the architecture that can be extended
improving documentation
tackling Big Issues from the future roadmap
improving testing
reviewing pull requests
Thank you for all your contributions :heart:
Set up the environment#
Development requires, at a minimum:
nodejs >=16,!=17,<19
python >=3.8,<3.11.0a0
jupyterlab >=4.0.5,<5.0.0a0
It is recommended to use a virtual environment (e.g. virtualenv
or conda env
)
for development.
To use the same environment as the binder demo (recommended):
conda env update -n jupyterlab-lsp --file binder/environment.yml # create a conda env
conda activate jupyterlab-lsp # activate it
Or with pip
:
pip install -r requirements/dev.txt # in a virtualenv, probably
sudo apt-get install nodejs # ... e.g. on debian/ubuntu
The Easy Way#
Once your environment is created and activated, on Linux/OSX you can run:
bash binder/postBuild
This performs all the basic setup steps, and is used for the binder demo.
The Hard Way#
Install jupyter-lsp
from source in your virtual environment:
python -m pip install -e python_packages/jupyter_lsp --ignore-installed --no-deps -vv
Enable the server extension:
jupyter server extension enable --sys-prefix --py jupyter_lsp
Install npm
dependencies, build TypeScript packages, and link
to JupyterLab for development:
jlpm bootstrap
# if you installed `jupyterlab_lsp` before uninstall it before running the next line
jupyter labextension develop python_packages/jupyterlab_lsp/ --overwrite
# optional, only needed for running a few tests for behaviour with missing language servers
jupyter labextension develop python_packages/klingon_ls_specification/ --overwrite
Note: on Windows you may need to enable Developer Mode first, as discussed in jupyterlab#9564
Frontend Development#
To rebuild the schemas, packages, and the JupyterLab app:
jlpm build
jupyter lab build
To watch the files and build continuously:
jlpm watch # leave this running...
jupyter lab --watch # ...in another terminal
Now after each change to TypesScript files wait until both watchers finish compilation, and then refresh the JupyterLab in your browser.
Note: the backend schema is not included in
watch
, and is only refreshed bybuild
To check and fix code style:
jlpm lint
To run test the suite (after running jlpm build
or watch
):
jlpm test
To run tests matching specific phrase, forward -t
argument over yarn and lerna to the test runners with two --
:
jlpm test -- -- -t match_phrase
To verify the webpack build wouldn’t include problematic vendored dependencies:
python scripts/distcheck.py
Server Development#
Testing jupyter-lsp
#
python scripts/utest.py
Documentation#
To build the documentation:
python scripts/docs.py
To watch documentation sources and build continuously:
python scripts/docs.py --watch
To check internal links in the docs after building:
python scripts/docs.py --check --local-only
To check internal and external links in the docs after building:
python scripts/docs.py --check
Note: you may get spurious failures due to rate limiting, especially in CI, but it’s good to test locally
Browser-based Acceptance Tests#
The browser tests will launch JupyterLab on a random port and exercise the
Language Server features with Robot Framework and SeleniumLibrary. It
is recommended to peruse the Robot Framework User’s Guide (and the existing
.robot
files in atest
) before working on tests in anger.
First, ensure you’ve prepared JupyterLab for jupyterlab-lsp
frontend and server development.
Prepare the environment:
conda env update -n jupyterlab-lsp --file requirements/atest.yml
or with pip
pip install -r requirements/atest.txt # ... and install geckodriver, somehow
sudo apt-get install firefox-geckodriver # ... e.g. on debian/ubuntu
Run the tests:
python scripts/atest.py
The Robot Framework reports and screenshots will be in atest/output
, with
<operating system>_<python version>_<attempt>.<log|report>.html
and subsequent screenshots
being the most interesting
artifact, e.g.
atest/
output/
linux_37_1.log.html
linux_37_1.report.html
linux_37_1/
screenshots/
Customizing the Acceptance Test Run#
By default, all of the tests will be run, once.
The underlying robot
command supports a vast number of options and many
support wildcards (*
and ?
) and boolean operators (NOT
, OR
). For more,
start with
simple patterns.
Run a suite#
python scripts/atest.py --suite "05_Features.Completion"
Run a single test#
python scripts/atest.py --test "Works When Kernel Is Idle"
Run test with a tag#
Tags are preferable to file names and test name matching in many settings, as they are aggregated nicely between runs.
python scripts/atest.py --include feature:completion
… or only Python completion
python scripts/atest.py --include feature:completionANDlanguage:python
Just Keep Testing with ATEST_RETRIES
#
Run tests, and rerun only failed tests up to two times:
ATEST_RETRIES=2 python scripts/atest.py --include feature:completion
After running a bunch of tests, it may be helpful to combine them back together
into a single log.html
and report.html
with
rebot.
Like atest.py
, combine.py
also passes through extra arguments
python scripts/combine.py
Troubleshooting#
If you see the following error message:
Parent suite setup failed: TypeError: expected str, bytes or os.PathLike object, not NoneType
it may indicate that you have no
firefox
, orgeckodriver
installed (or discoverable in the search path).If a test suite for a specific language fails it may indicate that you have no appropriate server language installed (see LANGUAGESERVERS)
If you are seeing errors like
Element is blocked by .jp-Dialog
, caused by the JupyterLab Build suggested dialog, (likely if you have been usingjlpm watch
) ensure you have a “clean” lab (with production assets) with:jupyter lab clean jlpm build jlpm lab:link jupyter lab build --dev-build=False --minimize=True
and re-run the tests.
To display logs on the screenshots, configure the built-in
ILSPLogConsole
console, to use the'floating'
implementation.If you see:
SessionNotCreatedException: Message: Unable to find a matching set of capabilities
geckodriver >=0.27.0
requires an actual Firefox executable. Several places will be checked (including whereconda-forge
installs, as in CI): to test a Firefox not on yourPATH
, set the following environment variable:export FIREFOX_BINARY=/path/to/firefox # ... unix set FIREFOX_BINARY=C:\path\to\firefox.exe # ... windows
If you see
Element ... could not be scrolled into view
in theOpen Context Menu for File
step check if you have an alternative file browser installed (such asjupyterlab-unfold
) which might interfere with testing (it is recommended to run the tests in an separated environment)
Formatting#
Minimal code style is enforced with pytest-flake8
during unit testing. If installed,
pytest-black
and pytest-isort
can help find potential problems, and lead to
cleaner commits, but are not enforced during CI tests (but are checked during lint).
You can clean up your code, and check for using the project’s style guide with:
python scripts/lint.py
Specs#
While language servers can be configured by the user using a simple JSON or Python configuration file, it is preferable to provide users with an option that does not require manual configuration. The language server specifications (specs) wrap the configuration (as would be defined by the user) into a Python class or function that can be either:
distributed using PyPI/conda-forge and made conveniently available to users for
pip install
and/orconda install
contributed to the collection of built-in specs of jupyter-lsp by opening a PR (preferable for popular language servers, say >100 users)
In either case the detection of available specifications uses Python entry_points
(see the [options.entry_points]
section in jupyter-lsp setup.cfg).
If an advanced user installs, locates, and configures, their own language server it will always win vs an auto-configured one.
Writing a spec#
A spec is a Python callable (a function, or a class with __call__
method) that accepts a single argument, the
LanguageServerManager
instance, and returns a dictionary of the form:
{
"python-language-server": { # the name of the implementation
"version": SPEC_VERSION, # the version of the spec schema (an integer)
"argv": ["python", "-m", "pyls"], # a list of command line arguments
"languages": ["python"], # a list of languages it supports
"mime_types": ["text/python", "text/x-ipython"]
}
}
The above example is only intended as an illustration and not as an up-to-date guide.
For details on the dictionary contents, see the schema definition and built-in specs.
Basic concepts (meaning of the argv
and languages
arguments) are also explained in the configuration files documentation.
When contributing a specification we recommend to make use of the helper classes and other utilities that take care of the common use-cases:
ShellSpec
helps to create specs for servers that can be started from command-linePythonModuleSpec
is useful for servers which are Python modulesNodeModuleSpec
will take care of finding Node.js modules
See the built-in built-in specs for example implementations.
The spec should only be advertised if the command could actually be run:
its runtime/interpreter (e.g.
julia
,nodejs
,python
,r
,ruby
) is installedthe language server itself is installed (e.g.
python-language-server
)
otherwise an empty dictionary ({}
) should be returned.
Common Concerns#
some language servers need to have their connection mode specified
the
stdio
interface is the only one supported byjupyter_lsp
PRs welcome to support other modes!
because of its VSCode heritage, many language servers use
nodejs
LanguageServerManager.nodejs
will provide the location of our best guess at where a user’snodejs
might be found
some language servers are hard to start purely from the command line
use a helper script to encapsulate some complexity, or
use a command argument of the interpreter is available (see the r spec and julia spec for examples)
Example: making a pip-installable cool-language-server
spec#
Consider the following (absolutely minimal) directory structure:
- setup.py
- jupyter_lsp_my_cool_language_server.py
You should consider adding a LICENSE, some documentation, etc.
Define your spec:
# jupyter_lsp_my_cool_language_server.py
from shutil import which
def cool(app):
cool_language_server = shutil.which("cool-language-server")
if not cool_language_server:
return {}
return {
"cool-language-server": {
"version": 1,
"argv": [cool_language_server],
"languages": ["cool"],
"mime_types": ["text/cool", "text/x-cool"]
}
}
Tell pip
how to package your spec:
# setup.py
import setuptools
setuptools.setup(
name="jupyter-lsp-my-cool-language-server",
py_modules=["jupyter_lsp_my_cool_language_server"],
entry_points={
"jupyter_lsp_spec_v1": [
"cool-language-server = jupyter_lsp_my_cool_language_server:cool"
]
}
)
Test it!
python -m pip install -e .
Build it!
python setup.py sdist bdist_wheel
Debugging#
Adjust loggingLevel
in the Advanced Settings Editor
-> Language Server
to see more log messages.
For robot tests set:
Configure JupyterLab Plugin {"loggingConsole": "floating", "loggingLevel": "debug"}
Extend jupyterlab-lsp#
Note: the API is likely to change in the future; your suggestions are welcome!
How to add a new LSP feature?#
Features (as well as other parts of the frontend) reuse the
JupyterLab plugins system.
Each plugin is a TypeScript package exporting
one or more JupyterFrontEndPlugin
s (see
the JupyterLab extesion developer tutorial
for an overview). Each feature has to register itself with the FeatureManager
(which is provided after requesting ILSPFeatureManager
token) using
register(options: IFeatureOptions)
method.
Your feature specification should follow the IFeature
interface, which can be
divided into three major parts:
editorIntegrationFactory
: constructors for the feature-CodeEditor integrators (implementing theIFeatureEditorIntegration
interface), one for each supported CodeEditor (e.g. CodeMirror or Monaco); for CodeMirror integration you can base your feature integration on the abstractCodeMirrorIntegration
class.labIntegration
: an optional object integrating feature with the JupyterLab interfacecapabilities
: an optional object defining the client capabilities implemented by your feature,optional fields for easy integration of some of the common JupyterLab systems, such as:
settings system
commands system (including context menu)
For further integration with the JupyterLab, you can request additional JupyterLab tokens (consult JupyterLab documentation on core tokens).
How to override the default implementation of a feature?#
You can specify a list of extensions to be disabled the the feature manager
passing their plugin identifiers in supersedes
field of IFeatureOptions
.
How to integrate a new code editor implementation?#
CodeMirrorEditor
code editor is supported by default, but any JupyterLab
editor implementing the CodeEditor.IEditor
interface can be adapted for the
use with the LSP extension. To add your custom code editor (e.g. Monaco) after
implementing a CodeEditor.IEditor
interface wrapper (which you would have
anyways for the JupyterLab integration), you need to also implement a virtual
editor (IVirtualEditor
interface) for it.
Why virtual editor?#
The virtual editor takes multiple instances of your editor (e.g. in a notebook) and makes them act like a single editor. For example, when “onKeyPress” event is bound on the VirtualEditor instance, it should be bound onto each actual code editor; this allows the features to be implemented without the knowledge about the number of editor instances on the page.
How to register the implementation?#
A virtualEditorManager
will be provided if you request
ILSPVirtualEditorManager
token; use
registerEditorType(options: IVirtualEditorType<IEditor>)
method passing a name
that you will also use to identify the code editor, the editor class, and your
VirtualEditor constructor.
How to integrate a new DocumentWidget
?#
JupyterLab editor widgets (such as Notebook or File Editor) implement
IDocumentWidget
interface. Each such widget has to adapted by a
WidgetAdapter
to enable its use with the LSP extension. The role of the
WidgetAdapter
is to extract the document metadata (language, mimetype) and the
underlying code editor (e.g. CodeMirror or Monaco) instances so that other parts
of the LSP extension can interface with them without knowing about the
implementation details of the DocumentWidget (or even about the existence of a
Notebook construct!).
Your custom WidgetAdapter
implementation has to register itself with
WidgetAdapterManager
(which can be requested with ILSPAdapterManager
token),
calling registerAdapterType(options: IAdapterTypeOptions)
method. Among the
options, in addition to the custom WidgetAdapter
, you need to provide a
tracker (IWidgetTracker
) which will notify the extension via a signal when a
new instance of your document widget is getting created.
How to add a custom magic or foreign extractor?#
It is now possible to register custom code replacements using
ILSPCodeOverridesManager
token and to register custom foreign code extractors
using ILSPCodeExtractorsManager
token, however this API is considered
provisional and subject to change.
Future plans for transclusions handling#
We will strive to make it possible for kernels to register their custom syntax/code transformations easily, but the frontend API will remain available for the end-users who write their custom syntax modifications with actionable side-effects (e.g. a custom IPython magic which copies a variable from the host document to the embedded document).
How to add custom icons for the completer?#
Prepare the icons in the SVG format (we use 16 x 16 pixels, but you should be fine with up to 24 x 24). You can load them for webpack in typescript using imports if you include a
typings.d.ts
file with the following content:declare module '*.svg' { const script: string; export default script; }
in your
src/
. You should probably keep the icons in yourstyle/
directory.Prepare
CompletionKind
→IconSvgString
mapping for the light (and optionally dark) theme, implementing theICompletionIconSet
interface. We have an additionalKernel
completion kind that is used for completions provided by kernel that had no recognizable type provided.Provide all other metadata required by the
ICompletionTheme
interface and register it onILSPCompletionThemeManager
instance usingregister_theme()
method.Provide any additional CSS styling targeting the JupyterLab completer elements inside of
.lsp-completer-theme-{id}
, e.g..lsp-completer-theme-material .jp-Completer-icon svg
for the material theme. Remember to include the styles by importing the in one of the source files.
For an example of a complete theme see theme-vscode.
Extend jupyter-lsp#
Language Server Specs#
Language Server Specs can be configured by Jupyter users, or distributed by third parties as python or JSON files. Since we’d like to see as many Language Servers work out of the box as possible, consider contributing a spec, if it works well for you!
Message Listeners#
Message listeners may choose to receive LSP messages immediately after being
received from the client (e.g. jupyterlab-lsp
) or a language server. All
listeners of a message are scheduled concurrently, and the message is passed
along once all listeners return (or fail). This allows listeners to, for
example, modify files on disk before the language server reads them.
If a listener is going to perform an expensive activity that shouldn’t block delivery of a message, a non-blocking technique like IOLoop.add_callback and/or a queue should be used.
Add a Listener with entry_points
#
Listeners can be added via entry_points by a package installed in the same
environment as notebook
:
## setup.cfg
[options.entry_points]
jupyter_lsp_listener_all_v1 =
some-unique-name = some.module:some_function
jupyter_lsp_listener_client_v1 =
some-other-unique-name = some.module:some_other_function
jupyter_lsp_listener_server_v1 =
yet-another-unique-name = some.module:yet_another_function
At present, the entry point names generally have no impact on functionality aside from logging in the event of an error on import.
Add a Listener with Jupyter Configuration#
Listeners can be added via traitlets
configuration, e.g.
## jupyter_server_config.jsons
{
'LanguageServerManager':
{
'all_listeners': ['some.module.some_function'],
'client_listeners': ['some.module.some_other_function'],
'server_listeners': ['some.module.yet_another_function']
}
}
Add a listener with the Python API#
lsp_message_listener
can be used as a decorator, accessed as part of a
serverextension
.
This listener receives all messages from the client and server, and prints them out.
from jupyter_lsp import lsp_message_listener
def load_jupyter_server_extension(nbapp):
@lsp_message_listener("all")
async def my_listener(scope, message, language_server, manager):
print("received a {} {} message from {}".format(
scope, message["method"], language_server
))
scope
is one of client
, server
or all
, and is required.
Listener options#
Fine-grained controls are available as part of the Python API. Pass these as
named arguments to lsp_message_listener
.
language_server
: a regular expression of language serversmethod
: a regular expression of LSP JSON-RPC method names
Releasing#
jupyterlab-lsp
and jupyter-lsp
releases may require building both the python
package and nodejs packages.
Updating Version Strings#
Use the bump_versions
script to manage the version strings:
python scripts/bump_versions.py
Check the version strings across the various files:
python scripts/integrity.py
TODO: create a
release.py
script #88
The PyPI version (jupyter-lsp) must be updated in the following places:
python_packages/jupyter_lsp/jupyter_lsp/_version.py
(canonical).github/workflows/job.test.yml
CHANGELOG.md
The npm version of jupyterlab-lsp
must be updated in the following places:
packages/jupyterlab-lsp/package.json
>version
(canonical).github/workflows/job.test.yml
packages/metapackage/package.json
CHANGELOG.md
The npm version of lsp-ws-connection
must be updated in the following places:
packages/lsp-ws-connection/package.json
>version
(canonical)packages/jupyterlab-lsp/package.json
CHANGELOG.md
The JupyterLab version (if a newer is supported or required) needs to be updated in:
packages/jupyterlab-lsp/package.json
>devDependencies
>@jupyterlab/application
(canonical)binder/environment.yml
requirements/lab.txt
.github/workflows/job.test.yml
README.md
Releasing:#
Note: “smoke source install” step on CI will fail when bumping internal dependencies until those are published on NPM. Make sure to release those first and re-run this check then.
cd packages/lsp-ws-connection
npm publish --access public
cd -
cd packages/completion-theme
npm publish --access public
cd -
cd packages/theme-material
npm publish --access public
cd -
cd packages/theme-vscode
npm publish --access public
cd -
cd packages/jupyterlab-lsp
npm publish --access public
cd -
./scripts/publish_pypi.sh
Changelog#
@jupyter-lsp/jupyterlab-lsp 5.0.0-beta.0
#
fix most regressions caught by tests in alpha
reopen diagnostics panel on reload
use toasts for notifications
@jupyter-lsp/jupyterlab-lsp 5.0.0-alpha.0
#
maintenance:
support JupyterLab 4
Requires JupyterLab >=4.0.5,<5.0.0a0
@jupyter-lsp/jupyterlab-lsp 4.2.0
(2023-05-28)#
features:
diagnostics can be ignored by severity level with new
ignoreSeverities
setting (#940)
jupyter-lsp 2.2.0
(2023-05-28)#
@jupyter-lsp/jupyterlab-lsp 4.1.0
(2023-04-24)#
jupyter-lsp 2.1.0
(2023-04-24)#
features:
make
.virtual_documents
optional - addedrequires_documents_on_disk
spec field (defaultTrue
, will becomeFalse
in next major version) (#930)
@jupyter-lsp/jupyterlab-lsp 4.0.1
(2023-03-21)#
bug fixes
overrides from
overrides.json
are now picked up again (#919)
jupyter-lsp 2.0.1
(2023-03-21)#
bug fixes:
pyright schema now includes required
python.
prefixes (#919)
@jupyter-lsp/jupyterlab-lsp 4.0.0
(2023-03-15)#
Requires JupyterLab >=3.6.0,<4.0.0a0
and Python 3.8 or newer.
features:
implement jump target selector and jump to references ([#739])
implement settings UI using native JupyterLab 3.3 UI (#778)
add option to show hover tooltip automatically (#864, thanks @yamaton)
implement eliding for long paths/files in completer (#893)
allow to pass default workspace config (
serverSettings
) in specs (#856)
bug fixes:
use correct websocket URL if configured as different from base URL (#820, thanks @MikeSem)
clean up all completer styles when completer feature is disabled (#829).
fix
undefined
being inserted for path-like completion items with noinsertText
(#833)reduce signature flickering when typing and hover flicker when moving mouse (#836)
fix sporadic misplacement of hover tooltips (#860, thanks @yamaton)
fix hover tooltip not updated after character deletions (#867, thanks @yamaton)
handle potential race condition in feature settings loading (#882)
refactoring:
changed NPM packages namespace from
@krassowski
to@jupyter-lsp
([#862])move client capabilities to features (#738)
downstreams:
documentation:
add missing
--channel
to conda instruction for texlab (#789, thanks @justin-f-perez)remove references to pylsp fork (#800 and #814, thanks @joelostblom and @nickfong)
add Robot Framework language server (#724, thanks @bollwyvl)
add a list of third-party and community language servers (#826, thanks @cccs-jc)
fix documentation of
.lsp_symlink
workaround ([#828])
maintenance:
bump minimum required JupyterLab version to 3.3 (
>=3.3.0,<4.0.0a0
)bump minimum required Node.js version to 14.0 (12.0 reached EOL in April)
use newer
@jupyterlab/builder
which provides third-party license information (#882)
lsp-ws-connection 0.7.1
(2023-03-15)#
jupyter-lsp 2.0.0
(2023-03-15)#
dependencies:
uses
importlib_metadata
(orimportlib.metadata
on 3.10+) forentry_points
(#882)supports Python versions are 3.8 or newer
performance:
entry_point
discovery is deferred until server has started, improvingjupyter_server
startup time (#852)
allow to pass default workspace config (
serverSettings
) in specs (#856)
@krassowski/jupyterlab-lsp 3.10.1
(2022-03-21)#
bug fixes:
maintenance
@krassowski/jupyterlab-lsp 3.10.0
(2022-01-01)#
features:
bug fixes:
squash warnings and errors in web console (#732)
fix signature blur and fix formatting when no arguments are present (#734)
fixed with enabling of strict null checks:
previously changing kernels always led to restarting of LSP connection, even if the kernel language did not change; now the connection will be retained if possible
markdownRenderer
is no longer implicitly requireddiagnostics sorting with missing values for
source
andseverity
was improved and missing values will be consistently shown at the enddiagnostics placeholder was split into
Diagnostics are not available
andNo issues detected, great job!
which will now show up properly
maintenance:
@krassowski/code-jumpers 1.2.0
(2022-01-01)#
maintenance:
updates to API with respect to
null
/undefined
values in course strict null checks activation (#733)
@krassowski/jupyterlab-lsp 3.9.3
(2021-12-19)#
bug fixes:
workaround upstream issue in merging translation (#726, thanks @fcollonval)
@krassowski/jupyterlab-lsp 3.9.2
(2021-12-12)#
bug fixes:
prevent very long completion details text from extending the completer indefinitely (#698)
correct status translations (#700, thanks @fcollonval)
fix translations in status pop-up (#703)
workaround issue causing file rename when opening external files by jumping to them (#712, thanks @jepcor97)
fix sorting by “Line:Ch” and “Cell” in Diagnostics Panel (#717)
fix header border missing when scrolling in Diagnostics Panel (#717)
documentation improvements:
clarify that JupyterLab restart is needed after installation (#714, thanks @3coins)
@krassowski/completion-theme 3.2.0
(2021-12-12)#
features:
add
details-below
layout allowing to change the completer arrangement (#698)
jupyter-lsp 1.5.1
(2021-12-12)#
@krassowski/jupyterlab-lsp 3.9.1
(2021-10-24)#
bug fixes:
fix build issues making it difficult to reuse/extend the package (#696, thanks @cccs-jc)
jupyter-lsp 1.5.0
(2021-10-24):#
features:
add support for new
typescript-language-server
replacingjavascript-typescript-langserver
; despite the name both packages provide support for all four: JavaScript, JSX, TypeScript and TSX; the oldjavascript-typescript-langserver
can still be used, but it is no longer maintained and we will not be supported, and specs may be removed in the next major release (#697).
@krassowski/jupyterlab-lsp 3.9.0
(2021-10-17)#
features:
signature help box will now persist while typing the arguments of a function (#671)
the currently active argument will be highlighted in the signature help box
if the documentation exceeds a user-configurable number of lines the signature help box will only display the first line of the documentation and the following lines will be collapsed into an expandable details section.
the signature box is now displayed above the current line
the signature box takes up less space
you can now disable specific features in settings (#689)
bug fixes:
fix missing translation strings (#675)
fix kernel completions not showing up for R (#686)
fix tab completions not showing up in strings due to incomplete trigger kind invalidation (#686)
fix path completions reconciliation for
pyls
/pylsp
withIPython
(#686)improve escaping rule for IPython magics overrides (#688)
fix documentation panel not showing up when typing fast (#692)
@krassowski/jupyterlab-lsp 3.8.1
(2021-08-02)#
jupyter-lsp 1.4.1
(2021-08-02)#
bug fixes:
remove spurious
ValidationError
warnings for non-installed servers (#645, thanks @karlaspuldaro)reduce number and verbosity of logs on startup
@krassowski/jupyterlab-lsp 3.8.0
(2021-07-04)#
improvements:
bug fixes:
jupyter-lsp 1.4.0
(2021-07-04)#
features:
changes:
ShellSpec.is_installed()
signature changed; it now accepts theLanguageServerManagerAPI
rather than the resolved command location (ofstr
type); the specs using onlyis_installed_args
are not affected; as this method was only used by internally by the__call__
implementation (which was adjusted accordingly) this change should not break existing specs unless any of these methods were overridden in sub-classes.SpecBase
was moved totypes.py
; it can still be imported fromutils
, but doing so is discouragedShellSpec.solve()
was added to facilitate discovery of command location
jupyter-lsp 1.3.0
(2021-06-02)#
features:
add auto-detection of pyright server (#587, thanks @yuntan)
@krassowski/jupyterlab-lsp 3.7.0
(2021-05-31)#
features:
add ability to deactivate Kernel completions or LSP completion through the settings (#586, thanks @Carreau)
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 (#602)
log server messages in user-accessible console (#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)
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
andserverRequests
instead (#606)
jupyter-lsp 1.2.0
(2021-04-26)#
@krassowski/code-jumpers 1.1.0
(2021-04-26)#
features:
added translation support (#557, thanks @JessicaBarh)
@krassowski/jupyterlab-lsp 3.6.0
(2021-04-26)#
@krassowski/jupyterlab-lsp 3.5.0
(2021-03-22)#
features:
adds
%%bigquery
IPython cell magic support for BigQuery (#553, thanks @julioyildo)completions filtering can be set to case-insensitive in settings (#549)
completions filtering can hide exact matches (#549)
the extra information displayed next to the completion label now can include ‘detail’ (usually module/package of origin), and can be customized in settings (#549)
bug fixes:
prevents throwing a highlights error when adding new cell with Shift + Enter (#544)
fixes IPython
pinfo
andpinfo2
(?
and??
) for identifiers containings
(#547)fixes incorrect behaviour of LSP features in some IPython magics with single line of content (#560)
fixes name of jupyterlab-lsp package in JupyterLab
for extension authors:
minimal functional extractor and code overrides APIs are now exported; these APIs cab be subject to change in future releases (#562)
jupyter-lsp 1.1.4
(2021-02-21)#
@krassowski/jupyterlab-lsp 3.4.1
(2021-02-16)#
bug fixes:
fixed installation of the source version of the extension (causing build error if classic was not installed) (#526)
@krassowski/jupyterlab-lsp 3.4.0
(2021-02-14)#
features:
the priority of the completions from kernel can now be changed by switching new
kernelCompletionsFirst
setting (#520)completer panel will now always render markdown documentation if available (#520)
the implementation re-renders the panel as it is the best we can do until jupyterlab#9663 is merged
the completer now uses
filterText
andsortText
if available to better filter and sort completions (#520, #523)completer
suppressInvokeIn
setting was removed;suppressContinuousHintingIn
andsuppressTriggerCharacterIn
settings were added (#521)suppressContinuousHintingIn
by default includesdef
to improve the experience when writing function names (#521)long file paths are now collapsed if composed of more than two segments to avoid status popover and diagnostics panel getting too wide (#524)
bug fixes:
user-invoked completion in strings works again (#521)
completer documentation will now consistently show up after filtering the completion items (#520)
completions containing HTML-like syntax will be displayed properly (an upstream issue) (#520, #523)
diagnostics panel will no longer break when foreign documents (e.g.
%%R
cell magics) are removed (#522)
@krassowski/jupyterlab-lsp 3.3.1
(2021-02-07)#
bug fixes:
completion and signature suggestions get invalidated when editor changes (#507)
signature suggestions now invalidate on cursor move to another line or backwards too (#507)
LaTeX is now rendered in documentation panel of completer (#506)
completion response returned as plain text use pre tag to retain whitespace formatting (#506)
pre-formatted code font size was reduced to match font-size of the text in completion panel (#506)
completer no longer spans the entire screen if it has long entries (#506)
jupyter-lsp 1.1.3
(2020-02-07)#
features:
add config for the classic notebook server extension (#504)
@krassowski/jupyterlab-lsp 3.3.0
(2021-01-31)#
features:
bug fixes:
delayed completion suggestions will no longer show up if cursor moved to another line (#496)
changes in notebooks after kernel restart or file rename will now be recorded by the language server again (#496)
when either of kernel providers: kernel or LSP server fails, the completion from the other will still be shown (#496)
jupyter-lsp 1.1.2
(2021-01-31)#
bug fixes:
fixed issues with language server messages being truncated in certain circumstances on Windows
@krassowski/jupyterlab-lsp 3.2.0
(2021-01-24)#
features:
bug fixes:
jupyter-lsp 1.1.1
(2021-01-24)#
bug fixes:
PythonModuleSpec
no longer raises exception when the server module does not exist (#485)
@krassowski/jupyterlab-lsp 3.1.0
(2021-01-17)#
features
make the extension work with
jupyterlab-classic
- experimental, not all features are functional yet (#465)new status “Server extension missing” and a dialog with advice was added to help users with atypical configurations (#476)
for developers: the verbosity of console logs is now controllable from settings and set to warn by default (#480)
bug fixes:
namespace completions in R (after double and triple colon) now work properly (#449)
improved status icon contrast when status item is active (#465)
connection manager now properly keeps track of notebooks when multiple notebooks are open (#474)
new cells added after kernel restart now work properly; kernel changes are handled correctly (#478)
increase total timeout for language server connection (#479)
fix status communication during initialization (#479)
jupyter-lsp 1.1.0
(2021-01-17)#
features
added experimental detection of Julia and Jedi language servers (#481)
bug fixes:
@krassowski/jupyterlab-lsp 3.0.0
(2021-01-06)#
jupyter-lsp 1.0.0
(2021-01-06)#
@krassowski/jupyterlab-lsp 2.1.2
(2021-01-02)#
features
highlights can now be auto-removed from the cells/editors on blur (set
removeOnBlur
totrue
in settings) (#446)
bug fixes
improved performance of completion and highlights by minimising the number of highlight requests and GUI redraws (token checking, debouncing, acting on a single response only) (#433)
highlights now update after cell focus/blur events even if those do not trigger cursor movement (#433)
trigger characters auto-invoke now works in continuous hinting mode again (#434)
@krassowski/jupyterlab-lsp 2.1.1
(2020-12-15)#
bug fixes
fix crash “blank screen” caused by Mac command character included in jump-to schema file (#429)
jupyter-lsp 0.9.3
(2020-12-13)#
features
the virtual documents’ folder can be configured with
JP_LSP_VIRTUAL_DIR
orLanguageServerManager.virtual_documents_dir
, with a potential benefit for JupyterHub installations (the default value remains contents.root_dir /.virtual_documents
) (#416, thanks @fcollonval)
@krassowski/jupyterlab-lsp 2.1.0
(2020-12-13)#
features
added “click to jump” functionality (by default using Alt modifier) (#423)
added “jump back” command, by default activated with Alt + o (#423)
.virtual_documents
location can now be customized (#416)tokens are now exported making them available for import from other extensions (#414, thanks @martinRenou)
bug fixes
context menu commands are now correctly registered where previously specific conditions were leading to race conditions (#399, thanks @mnowacki-b)
handles characters that need escaping (spaces, non-ASCII characters) more robustly in files and folder names (#403, thanks @bollwyvl and @avaissi)
moving cells now triggers the document update immediately leading to immediate diagnostics update (#421)
changing cell type to
raw
ormarkdown
and then back tocode
properly unbinds/binds event handlers and updates document (#421)pasted cells are added to the LSP document immediately, without the need for the user to enter them (#421)
improved error message when language server cannot be found (#413, thanks @martinRenou)
developer documentation got improved (#412, thanks @karlaspuldaro)
@krassowski/code-jumpers 1.0.0
(2020-12-13)#
breaking changes
split away from
@krassowski/jupyterlab_go_to_definition
, renamed to@krassowski/code-jumpers
(#423):removed unused code
refactored history operations to track files and always use global location data
renamed
uri
tocontents_path
to help avoid programmer issues with characters requiring URI encoding (#406)
@krassowski/jupyterlab-lsp 2.0.8
(2020-10-25)#
bug fixes
custom cell syntax highlighting is now properly removed when no longer needed (#387)
the completer in continuous hinting now works well with the pasted text (#389)
continuous hinting suggestions will no longer show up if the only hint is the same as the current token (#391)
available options for hover modifier keys are now listed in the setting descriptions (#377)
@krassowski/jupyterlab-lsp 2.0.7
(2020-09-18)#
bug fixes
fix syntax highlighting in hover tooltips and reduce unnecessary padding and margin (#363)
greatly improve performance of hover action (#363)
improve support for expanded hovers tooltips using deprecated API (#363)
do not hide hover tooltips too eagerly (allowing selecting text/easy scrolling of longer tooltips) (#363)
@krassowski/jupyterlab-lsp 2.0.6
(2020-09-15)#
bug fixes
fix syntax highlighting of %%language cells slowing down editing in notebooks (#361)
@krassowski/jupyterlab-lsp 2.0.5
(2020-09-11)#
bug fixes
fix too aggressive overrides of IPython’s pinfo (
?
) and pinfo2 (??
) (#352)
@krassowski/jupyterlab-lsp 2.0.4
(2020-09-11)#
@krassowski/jupyterlab-lsp 2.0.2
(2020-09-07)#
bug fixes
fix code overrides not being registered properly (#340)
@krassowski/jupyterlab-lsp 2.0.1
(2020-09-07)#
bug fixes
bump version of
lsp-ws-connection
dependency to fix the LaTeX server issues (see #337)
jupyter-lsp 0.9.2
(2020-09-03)#
autodetects the
sql
language server for.sql
files (#328)diagnostics are provided by
sqlint
which requires Node 11+ to work well (in contrast to currently required Node 10+).
@krassowski/jupyterlab-lsp 2.0.0
(2020-09-03)#
features
support for JupyterLab 2.2 (#301)
completer now displays server-provided documentation, and a kernel icon for kernel suggestions without type information (#301)
add two icons themes for the completer (material and vscode) (#322)
the documentation by the completer can be turned on or off (#315)
continuous hinting (Hinterland mode) can be enabled in settings (#315)
tokens in which the completer should not be triggered can be changed (#315)
configuration for the following features is now exposed in the settings editor (#318):
diagnostics (display, filtering)
hover (modifier key)
rename operation status reporting got improved (#318)
replaced the generic status icons with code check icon (coloured differently according to the status) (#318)
added icons for all the features and their commands (#318)
refactored the codebase with a new architecture which allows dynamic features, document widget adapter, and code editor registration (#318)
the document in the connections list in the statusbar popover are now represented by easy-to-understand DocumentLocator (breadcrumbs) widget rather than an internal id (bacc006)
syntax highlighting mode is adjusted to the language with the majority of the code in an editor (#319)
copy diagnostics message and filter diagnostics from context menu of Diagnostic Panel (#330)
bug fixes
path-autocompletion issues were resolved upstream and this release adopts these changes
the missing caret and document connection icons were restored in the statusbar popover (#318)
pressing “Cancel” rename during rename now correctly aborts the rename operation (#318)
when a language server for a foreign document is not available an explanation is displayed (rather than the “Connecting…” status as before) (4e5b2ad)
when jump target is not found a message is now shown instead of raising an exception (00448d0)
fixed status message expiration and replacement (8798f2d), (#329)
fixed some context command rank issues introduced after an attempt of migration to nulls (#318)
@krassowski/jupyterlab-lsp 1.1.2
(2020-08-05)#
jupyter-lsp 0.9.1
(2020-08-05)#
autodetects the
texlab
language server for.tex
files (#288)diagnostics should be provided by
chktex
on save, but don’t yet appear, but can be configured through the Advanced Settings Editor to appear on save or change
@krassowski/jupyterlab-lsp 1.1.0
(2020-07-20)#
features
language servers can now be configured from the Advanced Settings Editor (#245)
bug fixes
fixes currently-highlighted token in dark editor themes against light lab theme (and vice versa) (#195)
restores sorting order-indicating caret icons in diagnostics panel table (#261)
handles document open and change operation ordering more predictably (#284)
fixes some pyflakes issues caused by line magics substitution (#293)
updated the link to the documentation of language servers (#294)
jupyter-lsp 0.9.0
(2020-07-20)#
lsp-ws-connection 0.5.0
(2020-07-20)#
@krassowski/jupyterlab-lsp 1.0.0
(2020-03-14)#
features
supports JupyterLab 2.0
@krassowski/jupyterlab_go_to_definition 1.0.0
(2020-03-14)#
features
supports JupyterLab 2.0
@krassowski/jupyterlab-lsp 0.8.0
(2020-03-12)#
features
opens a maximum of one WebSocket per language server (#165, #199)
lazy-loads language server protocol machinery (#165)
waits much longer for slow-starting language servers (#165)
cleans up documents, handlers, events, and signals more aggressively (#165)
ignores malformed diagnostic ranges, enabling markdown support (#165)
passes tests on Python 3.8 on Windows (#165)
improves support for rpy2 magic cells with parameters ( #206 )
bug fixes
reports files are open only after installing all handlers to avoid missing messages (#201)
lsp-ws-connection 0.4.0
(2020-03-12)#
jupyter-lsp 0.8.0
(2020-03-12)#
jupyter-lsp 0.7.0
#
bugfixes
didSave no longer causes unwanted messages in logs ( #187 )
@krassowski/jupyterlab-lsp 0.7.1
#
features
bugfixes
lsp-ws-connection 0.3.1
#
@krassowski/jupyterlab-lsp 0.7.0
#
features
reduced space taken up by the statusbar indicator ( #106 )
implemented statusbar popover with connections statuses ( #106 )
generates types for server data responses from JSON schema ( #110 )
added ‘rename’ function for notebooks, using shadow filesystem ( #115 )
added a UX workaround for rope rename issues when there is a SyntaxError in the Python code ( #127 )
added a widget panel with diagnostics (inspections), allowing to sort and explore diagnostics, and to go to the respective location in code (with a click); accessible from the context menu ( #129 )
all commands are now accessible from the command palette ( #142 )
bash LSP now also covers
%%bash
magic cell in addition to%%sh
( #144 )rpy2 magics received enhanced support for argument parsing in both parent Python document (re-written overrides) and exctracted R documents (improved foreign code extractor) ( #148, #153 )
console logs can now easily be redirected to a floating console windows for debugging of the browser tests (see CONTRIBUTING.md)
bugfixes
diagnostics in foreign documents are now correctly updated ( 133fd3d )
diagnostics are now always correctly displayed in the document they were intended for
the workaround for relative root path is now also applied on Mac ( #139 )
fixed LSP of R in Python (
%%R
magic cell from rpy2) ( #144 )completion now work properly when the kernel is shut down ( #146 )
a lowercase completion option selected from an uppercase token will now correctly substitute the incomplete token ( #143 )
didSave()
is emitted on file save, enabling the workaround used by R language server to lazily loadlibrary(tidyverse)
( #95, #147, )signature feature is now correctly working in notebooks ( #140 )
lsp-ws-connection 0.3.0
#
jupyter-lsp 0.7.0b0
#
@krassowski/jupyterlab-lsp 0.6.1
#
features
adds an indicator to the statusbar
and many other improvements, see the release notes
dependencies
removes unused npm dependencies
@krassowski/jupyterlab-lsp 0.6.0
#
features
allows “rename” action in file editor
bugfixes
handles some non-standard diagnostic responses
testing
adds browser-based testing for file editor
dependencies
requires
jupyter-lsp
jupyter-lsp 0.6.0b0
#
features
starts language servers on demand
accepts configuration via Jupyter config system (traitlets) and python
entry_point
sautodetects language servers for bash, CSS, LESS, SASS, Dockerfile, YAML, JS, TypeScript, JSX, TSX, JSON, YAML
Roadmap#
If a feature you would like is not on the lists above, please feel free to suggest it by opening a new issue.
Front End#
improved code navigation when there are multiple jump targets
system of settings, including options:
to change the verbosity of signature documentation hints (number of lines to be shown)
custom foreign extractors allowing to customize behaviour for magics
code actions (allowing to “quick fix” a typo, etc.)
code formatting
gutter with linter results
use the kernel session for autocompletion in FileEditor if available (PR welcome)
Backend#
#49 cookiecutter for pip-installable specs
add hook system to allow serverextensions/kernels to modify, inspect and react to LSP messages
Architecture#
As-Is#
These are how we think everything works in the current master
branch.
Front End#
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[2], line 1
----> 1 get_ipython().run_line_magic('dot', 'dot/as-is/frontend.dot')
File ~/checkouts/readthedocs.org/user_builds/jupyterlab-lsp/conda/v5.0.0b0/lib/python3.10/site-packages/IPython/core/interactiveshell.py:2432, in InteractiveShell.run_line_magic(self, magic_name, line, _stack_depth)
2430 kwargs['local_ns'] = self.get_local_scope(stack_depth)
2431 with self.builtin_trap:
-> 2432 result = fn(*args, **kwargs)
2434 # The code below prevents the output from being displayed
2435 # when using magics with decorator @output_can_be_silenced
2436 # when the last Python token in the expression is a ';'.
2437 if getattr(fn, magic.MAGIC_OUTPUT_CAN_BE_SILENCED, False):
Cell In[1], line 10, in dot(line, cell)
8 @IPython.core.magic.register_line_cell_magic
9 def dot(line, cell=None):
---> 10 src = graphviz.Source(pathlib.Path(line).read_text() if line else cell)._repr_svg_()
11 src = re.sub(r"<svg (.*)viewBox", "<svg viewBox", src, flags=re.M | re.DOTALL)
12 return IPython.display.SVG(data=src)
AttributeError: 'Source' object has no attribute '_repr_svg_'
Positioning system#
Back End#
Proposals#
Some fragments of how the architecture could change in the future, and why (or why not) they might be a good idea.
Reorganize client source with lerna and typescript projects #76#
TBD
Add DiagnosticsManager, refactor DiagnosticPanel #176#
TBD
Multiple sources of LSP messages on frontend and backend #184#
TBD
Use mime types from server spec for language detection #190#
TBD
Formalize and extend language transclusion #191#
TBD