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.
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 in stdio
mode (as
opposed to tcp
),ls -l
is represented as ["ls", "-l"]
while
mkdir "new directory"
should be split into ["mkdir", "new directory"]
;
If you have Python installed, you can use shlex.split("your command")
to
get such an array.languages
which the language server will respond to, andversion
of the spec (currently 2
)mime_types
by which the notebooks and files will be matched to the language
server:language_info
/mimetype
element of kernel_info response (with fallback on to cell metadata if
missing from kernel response)DocumentRegistry
file type by
matching the contentsModel
against the registered file types using
getFileTypeForModel()
method (if multiple MIME types are present, the
first one will be used).requires_documents_on_disk
should be false
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"
}
}
default:
None
An absolute path to your nodejs
executable. If None
, nodejs
will be
detected in a number of well-known places.
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.
default:
[]
Absolute paths to search for directories named node_modules
, such as
nodejs
-backed language servers. The order is, roughly:
notebook
or lab
was launchedstaging
folderconda
puts global node modulesdefault:
[]
Additional places jupyter-lsp
will look for node_modules
. These will be
checked before node_roots
, and should not contain the trailing
node_modules
.
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
.
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.
To enable integration of language servers with Jupyter notebooks this extensions
assumes that the language_info
section of [kernel_info_reply
][kernel_info]
is complete and properly returned by the Kernel. In particular the following
elements are required:
.ipynb
), derived
from file_extension
field of language_info
, will be added to the name of
the notebook when communicating with the language server to satisfy the file
extension check.mimetype
field of
language_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 the
mime_types
list of language server specification.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").