#!/usr/bin/env python
# coding: utf-8
# ## 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](./Configuring.html#autodetect)
#
# You can add another language server for languages that are not listed on this
# page:
#
# - using a minimal JSON or Python
# [configuration file](./Configuring.html#language-servers) (good for
# experimenting or configuring a niche server), or
# - contributing a [full specification](./Contributing.html#specs) (to enable
# better integration and help other users of the same language)
#
# The existing language servers are listed on the [official
# list][lsp-implementations] and on the [community-curated list][langserver].
#
# 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`.
#
# [language-server]:
# https://microsoft.github.io/language-server-protocol/specification
# [langserver]: https://langserver.org
# [lsp-implementations]:
# https://microsoft.github.io/language-server-protocol/implementors/servers
# In[ ]:
import pathlib
import IPython
from jinja2 import Template
from jupyter_lsp import LanguageServerManager
# In[ ]:
mgr = LanguageServerManager(extra_node_roots=[str(pathlib.Path.cwd().parent)])
# In[ ]:
mgr.init_language_servers()
# In[ ]:
def lang_server_table(specs):
return IPython.display.HTML(
Template(
"""
Languages |
Implementation |
Installation |
{% for key, spec in specs.items() %}
{% for lang in spec.languages %}
{{ lang }}
{% endfor %}
|
{{key}}
|
{% for pkgmgr, inst in spec.install.items() %}
- {{pkgmgr}}:
{{ inst }}
{% endfor %}
|
{% endfor %}
"""
).render(specs=specs)
)
# ### 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.
# In[ ]:
nb_langs = [
"pylsp",
"r-languageserver",
"julia-language-server",
"jedi-language-server",
# "robotframework_ls",
]
lang_server_table(
{
key: spec
for key, spec in sorted(mgr.all_language_servers.items())
if key in nb_langs
}
)
# 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](./Configuring.html#making-custom-servers-work-with-notebooks).
# ### Servers tested with file editor
# #### Servers requiring Node.js
#
# These servers have mostly been tested with file editors.
# In[ ]:
npm_specs = {
key: spec
for key, spec in sorted(mgr.all_language_servers.items())
if "npm" in spec["install"]
}
lang_server_table(npm_specs)
# 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:
#
# ```bash
# 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](https://github.com/microsoft/vscode-languageserver-node),
# 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`:
# In[ ]:
IPython.display.Markdown(
Template(
"""```bash
jlpm add --dev {% for name, spec in specs.items() %} \\
{{ spec["install"]["npm"].split(" ")[-1] }}{% endfor %}
```
"""
).render(specs=npm_specs)
)
# 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](./Configuring.html#extra_node_roots).
# #### Standalone servers
#
# These servers have been mostly tested with file editor.
# In[ ]:
sci_langs = ["texlab"]
lang_server_table(
{key: spec for key, spec in mgr.all_language_servers.items() if key in sci_langs}
)
# ##### Example: Getting a $\LaTeX$ stack
#
# ```bash
# conda install --channel conda-forge tectonic texlab chktex
# ```
#
# This will install:
#
# - `tectonic`, a cross-platform $\LaTeX$ processing tool
# - note, it will download a large number of packages when first executed
# - `texlab`, a Language Server for `.tex` files that supports completion and
# reference navigation
# - `chktex`, 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 | [CybercentreCanada/jupyterlab-sql-editor] | |
# | GraphQL, SPARQL, Turtle | [jupyrdf/graph-lsp] | |
# | JSON | [jupyter-lsp/json-lsp] | (1) |
# | YAML | [jupyter-lsp/yaml-lsp] | (1) |
# | Scala | [scalameta/metals] | (2) |
#
# [jupyrdf/graph-lsp]: https://github.com/jupyrdf/graph-lsp
# [cybercentrecanada/jupyterlab-sql-editor]:
# https://github.com/CybercentreCanada/jupyterlab-sql-editor
# [jupyter-lsp/json-lsp]: https://github.com/jupyter-lsp/json-lsp
# [jupyter-lsp/yaml-lsp]: https://github.com/jupyter-lsp/yaml-lsp
# [scalameta/metals]: https://github.com/scalameta/metals
# - (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](./Configuring.html#example-scala-language-server-metals-integration).
# ### Troubleshooting
# In[ ]:
troubleshooting_data = {
key: spec
for key, spec in mgr.all_language_servers.items()
if (
"troubleshoot" in spec
# ignore trivial Node.js advice if only this is present
and spec["troubleshoot"] != "Node.js is required to install this server."
# ignore trivial shell advice if only this is present
and spec["troubleshoot"] != f"{spec['argv'][0]} not found."
)
}
IPython.display.HTML(
Template(
"""
{% for key, spec in specs.items() %}
{{ key }}
{{ spec.troubleshoot }}
{% endfor %}
"""
).render(specs=troubleshooting_data)
)