diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 000000000..e5e65321e
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,29 @@
+# CHANGELOG
+
+## `@krassowski/jupyter-lsp 0.6.1`
+
+- features
+ - adds an indicator to the statusbar
+- dependencies
+ - removes unused npm dependencies
+
+## `@krassowski/jupyter-lsp 0.6.0`
+
+- features
+ - allows "rename" action in file editor
+ - and many other improvements, see the [release notes](https://github.com/krassowski/jupyterlab-lsp/releases/tag/v0.6.0)
+- bugfixes
+ - handles some non-standard diagnostic responses
+- testing
+ - adds browser-based testing for file editor
+- dependencies
+ - requires `jupyter-lsp`
+
+## `jupyter-lsp 0.6.0`
+
+- features
+ - starts language servers on demand
+ - accepts configuration via Jupyter config system (traitlets) and python
+ `entry_point`s
+ - autodetects language servers for bash, CSS, LESS, SASS, Dockerfile, YAML, JS,
+ TypeScript, JSX, TSX, JSON, YAML
diff --git a/py_src/jupyter_lsp/CONTRIBUTING.md b/CONTRIBUTING.md
similarity index 77%
rename from py_src/jupyter_lsp/CONTRIBUTING.md
rename to CONTRIBUTING.md
index 5a8964407..d82c0fc40 100644
--- a/py_src/jupyter_lsp/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,168 +1,100 @@
-# Contribute to jupyter-lsp
+# Contribute to jupyterlab-lsp and jupyter-lsp :heart:
-`jupyter-lsp` is [open source](../../LICENSE) software, and all contributions
-conforming to good sense, good taste, and the
+`jupyter-lsp` and `jupyterlab-lsp` are [open source](./LICENSE) software, and
+all contributions conforming to good sense, good taste, and the
[Jupyter Code of Conduct][code-of-conduct] are welcome, and will be reviewed
by the contributors, time-permitting.
-## How to Help
+You can contribute to the project through:
-You can contribute to `jupyter-lsp` by:
-
-- creating [specs](#Specs)
+- creating language server [specs](#Specs)
- you can publish them yourself (it might be a single file)...
- or advocate for adding your spec to the [github repository][jupyterlab-lsp]
and its various distributions
- these are great first issues, as you might not need to know any python or
javascript
- improving [documentation](#Documentation)
-- tackling Big Issues from the [future roadmap](#Future-Roadmap-Items)
+- tackling Big Issues from the [future roadmap](./ROADMAP.md)
- improving [testing](#Testing)
- reviewing pull requests
-## Roadmap
-
-- release on `pip`
-- release on `conda`
-- [#49](https://github.com/krassowski/jupyterlab-lsp/issues/49)
- cookiecutter for pip-installable specs
+## Set up the environment
-## Future Roadmap Items
+Development requires:
-- add hook system to allow serverextensions/kernels to modify, inspect and
- react to LSP messages
+- `nodejs` 8 or later
+- `python` 3.5+
+- `jupyterlab` 1.1
-## Specs
+It is recommended to use a virtual environment (e.g. `virtualenv` or `conda env`)
+for development.
-It is convenient to collect common patterns for connecting to installed language
-servers as `pip`-installable packages that Just Work with `jupyter-lsp`.
-
-If an advanced user installs, locates, and configures, their own language
-server it will always win vs an auto-configured one.
-
-### Writing a spec
-
-> See the built-in [specs](./specs) for implementations and some
-> [helpers](./specs/utils.py).
-
-A spec is a python function that accepts a single argument, the
-`LanguageServerManager`, and returns a dictionary of the form:
-
-```python
-{
- "python-language-server": { # the name of the implementation
- "argv": ["python", "-m", "pyls"], # a list of command line arguments
- "languages": ["python"] # a list of languages it supports
- }
-}
+```bash
+conda env update -n jupyterlab-lsp # create a conda env
+source activate jupyterlab-lsp # activate it
+# or...
+pip install -r requirements-dev.txt # in a virtualenv, probably
+ # ... and install nodejs, somehow
```
-The spec should only be advertised if the command _could actually_ be run:
-
-- its runtime (e.g. `julia`, `nodejs`, `python`, `r`, `ruby`) is installed
-- the language server itself is installed (e.g. `python-language-server`)
+Install `jupyter-lsp` from source in your virtual environment:
-#### Common Concerns
-
-- some language servers need to have their connection mode specified
- - the `stdio` interface is the only one supported by `jupyter_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's `nodejs` might be found
-- some language servers are hard to start purely from the command line
- - use a helper script to encapsulate some complexity.
- - See the [r spec](./specs/r_languageserver.py) for an example
-
-#### 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
+```bash
+python -m pip install -e .
```
-> You should consider adding a LICENSE, some documentation, etc.
-
-Define your spec:
+Enable the server extension:
-```python
-# 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": {
- "argv": [cool_language_server],
- "languages": ["cool"]
- }
- }
+```bash
+jupyter serverextension enable --sys-prefix --py jupyter_lsp
```
-Tell `pip` how to package your spec:
+Install `npm` dependencies, build TypeScript packages, and link
+to JupyterLab for development:
-```python
-# 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_v0": [
- "cool-language-server":
- "jupyter_lsp_my_cool_language_server:cool"
- ]
- }
-)
+```bash
+jlpm
+jlpm build
+jlpm lab:link
```
-Test it!
+## Frontend Development
+
+To rebuild the packages and the JupyterLab app:
```bash
-python -m pip install -e .
+jlpm build
+jupyter lab build
```
-Build it!
+To watch the files and build continuously:
```bash
-python setup.py sdist bdist_wheel
+jlpm build --watch # leave this running...
+jupyter lab --watch # ...in another terminal
```
-## Contributing to `jupyter-lsp`
-
-### Set up the environment
+To check and fix code style:
```bash
-conda env update -n jupyterlab-lsp # create a conda env
-source activate jupyterlab-lsp # activate it
-# or...
-pip install -r requirements-dev.txt # in a virtualenv, probably
- # ... and install nodejs, somehow
+jlpm lint
```
-Install a development version from `master` in your virtual environment:
+To run test the suite:
```bash
-python -m pip install -e .
-jupyter labextension install .
+jlpm test
```
-## Testing `jupyter-lsp`
+## Server Development
-### Unit & Code Style Tests
+### Testing `jupyter-lsp`
```bash
python scripts/utest.py
```
-### Browser-based Acceptance Tests
+## 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][].
@@ -171,7 +103,7 @@ Language Server features with [Robot Framework][] and [SeleniumLibrary][].
[seleniumlibrary]: https://github.com/robotframework/seleniumlibrary
First, ensure you've prepared JupyterLab for `jupyterlab-lsp`
-[development](../../README.md#development).
+[frontend](#frontend-development) and [server](#server-development) development.
Prepare the enviroment:
@@ -179,11 +111,9 @@ Prepare the enviroment:
conda env update -n jupyterlab-lsp --file environment-atest.yml
# or
pip install -r requirements-atest.txt # ... and install geckodriver, somehow
+apt-get install firefox-geckodriver # ... e.g. on debian/ubuntu
```
-> Ubuntu users can install geckodriver with `apt install firefox-geckodriver`.
-> Ensure you have run `jupyter labextension install .` in the root of the repository.
-
Run the tests:
```bash
@@ -239,8 +169,108 @@ black py_src
> - sphinx
> - one of the sphinx/ipynb connectors
-[language-server]: https://microsoft.github.io/language-server-protocol/specification
-[jupyter-server-proxy]: https://github.com/jupyterhub/jupyter-server-proxy
-[lsp-implementations]: https://microsoft.github.io/language-server-protocol/implementors/servers
[jupyterlab-lsp]: https://github.com/krassowski/jupyterlab-lsp.git
[code-of-conduct]: https://github.com/jupyter/governance/blob/master/conduct/code_of_conduct.md
+
+### Specs
+
+It is convenient to collect common patterns for connecting to installed language
+servers as `pip`-installable packages that Just Work with `jupyter-lsp`.
+
+If an advanced user installs, locates, and configures, their own language
+server it will always win vs an auto-configured one.
+
+#### Writing a spec
+
+> See the built-in [specs](./specs) for implementations and some
+> [helpers](./specs/utils.py).
+
+A spec is a python function that accepts a single argument, the
+`LanguageServerManager`, and returns a dictionary of the form:
+
+```python
+{
+ "python-language-server": { # the name of the implementation
+ "argv": ["python", "-m", "pyls"], # a list of command line arguments
+ "languages": ["python"] # a list of languages it supports
+ }
+}
+```
+
+The spec should only be advertised if the command _could actually_ be run:
+
+- its runtime (e.g. `julia`, `nodejs`, `python`, `r`, `ruby`) is installed
+- the language server itself is installed (e.g. `python-language-server`)
+
+##### Common Concerns
+
+- some language servers need to have their connection mode specified
+ - the `stdio` interface is the only one supported by `jupyter_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's `nodejs` might be found
+- some language servers are hard to start purely from the command line
+ - use a helper script to encapsulate some complexity.
+ - See the [r spec](./specs/r_languageserver.py) for an example
+
+##### 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:
+
+```python
+# 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": {
+ "argv": [cool_language_server],
+ "languages": ["cool"]
+ }
+ }
+```
+
+Tell `pip` how to package your spec:
+
+```python
+# 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_v0": [
+ "cool-language-server":
+ "jupyter_lsp_my_cool_language_server:cool"
+ ]
+ }
+)
+```
+
+Test it!
+
+```bash
+python -m pip install -e .
+```
+
+Build it!
+
+```bash
+python setup.py sdist bdist_wheel
+```
diff --git a/LANGUAGESERVERS.md b/LANGUAGESERVERS.md
new file mode 100644
index 000000000..add757d78
--- /dev/null
+++ b/LANGUAGESERVERS.md
@@ -0,0 +1,137 @@
+# Language Servers
+
+`jupyter-lsp` does not come with any Language Servers! However, we will try to use
+them if they _are_ installed and we know about them (you can disable this behavior
+by configuring [`autodetect`](#autodetect)).
+
+Use a package manager to install a [language server][lsp-implementations]
+(also [this list][langserver]) from the tables below: these implementations are
+tested to work with `jupyter-lsp`.
+
+| language | `npm install (-g)`, or `yarn/jlpm add (-g)` |
+| ------------------------- | :-----------------------------------------: |
+| bash | `bash-language-server` |
+| css
less
sass | `vscode-css-languageserver-bin` |
+| docker | `dockerfile-language-server-nodejs` |
+| html | `vscode-html-languageserver-bin` |
+| javascript
typescript | `javascript-typescript-langserver` |
+| json | `vscode-json-languageserver-bin` |
+| markdown | `unified-language-server` |
+| yaml | `yaml-language-server` |
+
+| language | `conda install -c conda-forge` | language-specific package manager |
+| -------- | :----------------------------: | :-----------------------------------------------: |
+| python | `python-language-server` | `pip install python-language-server` |
+| r | `r-languageserver` | `Rscript -e 'install.packages("languageserver")'` |
+
+[language-server]: https://microsoft.github.io/language-server-protocol/specification
+[langserver]: https://langserver.org
+[jupyter-server-proxy]: https://github.com/jupyterhub/jupyter-server-proxy
+[lsp-implementations]: https://microsoft.github.io/language-server-protocol/implementors/servers
+[jupyter-lsp]: https://github.com/krassowski/jupyterlab-lsp.git
+[jupyterlab]: https://github.com/jupyterlab/jupyterlab
+
+Don't see an implementation for the language server you need? You can
+[bring your own language server](#adding-custom-language-servers).
+
+> Please consider [contributing your language server spec](../../CONTRIBUTING.md#spec)
+> to `jupyter-lsp`!
+
+## Adding custom language servers
+
+### Jupyter config via `traitlets`
+
+Like the Jupyter Notebook server, JupyterHub and other Jupyter interactive computing
+tools, `jupyter-lsp` can be configured via [Python or JSON files][notebook-config]
+in _well-known locations_. You can find out where to put them on your system with:
+
+[notebook-config]: https://jupyter-notebook.readthedocs.io/en/stable/config.html
+
+```bash
+jupyter --paths
+```
+
+They will be merged from bottom to top, and the directory where you launch your
+`notebook` server wins, making it easy to check in to version control.
+
+```python
+# ./jupyter_notebook_config.json ---------- unique! -----------
+# | |
+# or e.g. V V
+# $PREFIX/etc/jupyter/jupyter_notebook_config.d/a-language-server-implementation.json
+{
+ "LanguageServerManager": {
+ "language_servers": {
+ "a-language-server-implementation": {
+ "argv": ["/absolute/path/to/a-language-server", "--stdio"],
+ "languages": ["a-language"]
+ }
+ }
+ }
+}
+```
+
+More complex configurations that can't be hard-coded may benefit from the python approach:
+
+```py
+# jupyter_notebook_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"]
+ },
+ "another-language-implementation": {
+ # if run like a script
+ "argv": [shutil.which("another-language-interpreter"), "another-language-server"],
+ "languages": ["another-language"]
+ }
+}
+```
+
+### Python `entry_points`
+
+`pip`-installable packages in the same environment as the Jupyter `notebook` server
+can be automatically detected as providing a language server spec. These are a
+little more involved: see [CONTRIBUTING](../../CONTRIBUTING.md).
+
+# Configuration Options
+
+Like `language_servers`, these can be configured via `jupyter_notebook_config.json`
+(or .py) or via command line arguments to `jupyter notebook` or `jupyter lab`.
+
+## nodejs
+
+> default: autodetect
+
+A custom absolute path to your `nodejs` executable.
+
+## autodetect
+
+> default: True
+
+`jupyter-lsp` will look for all [known language servers](#installing-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 `node_modules`, such as `nodejs`-backed language servers.
+The order is, roughly:
+
+- the folder where `notebook` or `lab` was launched
+- the JupyterLab `staging` folder
+- wherever `conda` puts global node modules
+- wherever 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`
diff --git a/README.md b/README.md
index 8a6386e3c..cea2b6961 100644
--- a/README.md
+++ b/README.md
@@ -1,85 +1,77 @@
-# Language Server Protocol integration for JupyterLab
+# Language Server Protocol integration for Jupyter(Lab)
[![Build Status](https://travis-ci.org/krassowski/jupyterlab-lsp.svg?branch=master)](https://travis-ci.org/krassowski/jupyterlab-lsp) [![Build Status](https://dev.azure.com/krassowskimichal/jupyterlab-lsp/_apis/build/status/jupyterlab-lsp?branchName=master)](https://dev.azure.com/krassowskimichal/jupyterlab-lsp/_build/latest?definitionId=1&branchName=master) [![codebeat badge](https://codebeat.co/badges/f55d0f28-8a84-4199-bc88-f2c306a9ce65)](https://codebeat.co/projects/github-com-krassowski-jupyterlab-lsp-master) [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/krassowski/jupyterlab-lsp/master?urlpath=lab%2Ftree%2Fexamples%2FPython.ipynb)
-_This extension is in its early days, but you are welcome to check it out, leave feedback and/or a PR_
+> _This project is in its early days, but you are welcome to check it out, leave feedback and/or a PR_
-## Features overview:
+Quick Links: **[Installation](#installation) | [Language Servers](./LANGUAGESERVERS.md) | [Updating](#updating) | [Changelog](./CHANGELOG.md) | [Roadmap](./ROADMAP.md) | [Contributing](./CONTRIBUTING.md)**
-### Implemented
+## Features
-Examples below are for Python, but it works as well for R:
+> Examples below are for Python, but work for R as well
-- hover over any piece of code; if an underline appears, you can press Ctrl to get a tooltip with function/class signature, module documentation or any other piece of information that the language server provides
+### Hover
- ![hover](https://raw.githubusercontent.com/krassowski/jupyterlab-lsp/master/examples/screenshots/hover.png)
+Hover over any piece of code; if an underline appears, you can press Ctrl
+to get a tooltip with function/class signature, module documentation or any other
+piece of information that the language server provides
-- linting: critical errors have red underline, warnings are orange, etc. Hover over the underlined code to see the linter's message
+![hover](https://raw.githubusercontent.com/krassowski/jupyterlab-lsp/master/examples/screenshots/hover.png)
- ![inspections](https://raw.githubusercontent.com/krassowski/jupyterlab-lsp/master/examples/screenshots/inspections.png)
+### Diagnostics
-- go to definition: use the context menu entries to jump to definitions
+Critical errors have red underline, warnings are orange, etc. Hover
+over the underlined code to see a more detailed message
- ![jump](https://raw.githubusercontent.com/krassowski/jupyterlab-lsp/master/examples/screenshots/jump_to_definition.png)
+![inspections](https://raw.githubusercontent.com/krassowski/jupyterlab-lsp/master/examples/screenshots/inspections.png)
-- highlight usages: just place your cursor on a variable, function etc and all the usages will be highlighted
+### Jump to Definition
-- auto invocation of completer on certain characters, for example '.' (dot) in Python
+Use the context menu entries to jump to definitions
- ![invoke](https://raw.githubusercontent.com/krassowski/jupyterlab-lsp/master/examples/screenshots/auto_invoke.png)
+![jump](https://raw.githubusercontent.com/krassowski/jupyterlab-lsp/master/examples/screenshots/jump_to_definition.png)
-- automatic signature suggestions
+### Highlight References
- ![signature](https://raw.githubusercontent.com/krassowski/jupyterlab-lsp/master/examples/screenshots/signature.png)
+Place your cursor on a variable, function, etc and all the usages will be highlighted
-- advanced autocompletion (even when the kernel is off);
+### Automatic Completion
- ![autocompletion](https://raw.githubusercontent.com/krassowski/jupyterlab-lsp/master/examples/screenshots/autocompletion.png)
+Certain characters, for example '.' (dot) in Python, will automatically trigger
+completion
- when a kernel is available the suggestions from the kernel (such as keys of a dict and columns of a DataFrame autocompletion) are merged with the suggestions from LSP (currently only in notebook).
+![invoke](https://raw.githubusercontent.com/krassowski/jupyterlab-lsp/master/examples/screenshots/auto_invoke.png)
-New in 0.6.0:
+### Automatic Signature Suggestions
-- automated LSP servers start and traitlets-based configuration
-- "rename" action in file editor
-- and many other improvements, see the [release notes](https://github.com/krassowski/jupyterlab-lsp/releases/tag/v0.6.0).
+Function signatures will automatically be displayed
-New in 0.6.1:
+![signature](https://raw.githubusercontent.com/krassowski/jupyterlab-lsp/master/examples/screenshots/signature.png)
-- removed unused dependencies
-- added an indicator to the statusbar
+### Kernel-less Autocompletion
-### Coming soon:
+Advanced static-analysis autocompletion without a running kernel
-- improved code navigation when there are multiple jump targets
-- autocompleter with documentation and sorting based on LSP suggestions
-- system of settings, including options:
- - to enable aggressive autocompletion (like in hinterland)
- - to change the verbosity of signature hints (whether to show documentation, number of lines to be shown)
-- "rename" action in notebooks
-- gutter with linter results (low priority)
-- use the kernel session for autocompletion in FileEditor if available (PR welcome)
+![autocompletion](https://raw.githubusercontent.com/krassowski/jupyterlab-lsp/master/examples/screenshots/autocompletion.png)
-If a feature you need is not on the lists above, please feel free to suggest it by opening a new [issue](https://github.com/krassowski/jupyterlab-lsp/issues).
-
-#### Hints
-
-- just like in old notebooks, you can still use the built-in Shift + Tab to get a signature in JupyterLab.
- This extension behaves well with this feature.
+> When a kernel is available the suggestions from the kernel (such as keys of a
+> dict and columns of a DataFrame autocompletion) are merged with the suggestions
+> from the Language Server (currently only in notebook).
## Prerequisites
- JupyterLab >=1.1,<1.2
+- Python 3.5+
+- nodejs 8+
## Installation
-For 0.6 version:
+For the current stable version:
-1. install and enable the server extension:
+1. install the server extension:
```bash
pip install jupyter-lsp
- jupyter serverextension enable --sys-prefix --py jupyter_lsp
```
2. install the frontend extension:
@@ -88,20 +80,35 @@ For 0.6 version:
jupyter labextension install @krassowski/jupyterlab-lsp
```
-3. install LSP servers for languages of your choice; for example, for Python ([pyls](https://github.com/palantir/python-language-server)) and R ([languageserver](https://github.com/REditorSupport/languageserver)) servers, use:
+3. install LSP servers for languages of your choice; for example, for Python
+ ([pyls](https://github.com/palantir/python-language-server)) and
+ R ([languageserver](https://github.com/REditorSupport/languageserver)) servers:
```bash
pip install python-language-server[all]
R -e 'install.packages("languageserver")'
```
- Please see our full list of [supported language servers](./py_src/jupyter_lsp/README.md#installing-language-servers) which includes installation hints for the common package managers (npm/pip/conda).
- In general, any LSP server from the [Microsoft's list](https://microsoft.github.io/language-server-protocol/implementors/servers/) should work after [some additional configuration](./py_src/jupyter_lsp/CONTRIBUTING.md#specs).
+ or from `conda-forge`
- Note: it may be worth visiting the repository of each server you install as many provide additional configuration options.
+ ```bash
+ conda install -c conda-forge python-language-server r-languageserver
+ ```
-4. (Optional) to enable opening files outside of the root directory (the place where you start JupyterLab),
- create `.lsp_symlink` and symlink your `home`, or any other location which includes the files that you wish to make possible to open in there:
+ Please see our full list of
+ [supported language servers](./LANGUAGESERVERS.md)
+ which includes installation hints for the common package managers (npm/pip/conda).
+ In general, any LSP server from the
+ [Microsoft list](https://microsoft.github.io/language-server-protocol/implementors/servers/)
+ should work after [some additional configuration](./CONTRIBUTING.md#specs).
+
+ Note: it may be worth visiting the repository of each server you install as
+ many provide additional configuration options.
+
+4. (Optional, Linux/OSX-only) to enable opening files outside of the root
+ directory (the place where you start JupyterLab), create `.lsp_symlink` and
+ symlink your `/home`, or any other location which includes the files that you
+ wish to make possible to open in there:
```bash
mkdir .lsp_symlink
@@ -109,62 +116,30 @@ For 0.6 version:
ln -s /home home
```
- If your user does not have sufficient permissions to traverse the entire path, you will not be able to open the file. A more detailed guide on symlinking (written for a related jupyterlab-go-to-definition extension) is available [here](https://github.com/krassowski/jupyterlab-go-to-definition/blob/master/README.md#which-directories-to-symlink).
+ If your user does not have sufficient permissions to traverse the entire path,
+ you will not be able to open the file. A more detailed guide on symlinking
+ (written for a related jupyterlab-go-to-definition extension) is available
+ [here](https://github.com/krassowski/jupyterlab-go-to-definition/blob/master/README.md#which-directories-to-symlink).
-### Updating the extension
+### Updating
-To update already installed extension:
+To update previously installed extensions:
```bash
pip install -U jupyter-lsp
jupyter labextension update @krassowski/jupyterlab-lsp
```
-#### Getting the latest alpha/beta/RC version
-
-Use install command (update does not seem to work) appending `@version` to the extension name, like this:
-
-```bash
-jupyter labextension install @krassowski/jupyterlab-lsp@0.6.1
-```
-
-## Development
-
-For a development install (requires `nodejs` 8 or later and `jupyterlab` 1.1),
-run the following in the repository directory:
-
-```bash
-jlpm
-jlpm build
-jlpm lab:link
-```
-
-To rebuild the packages and the JupyterLab app:
-
-```bash
-jlpm build
-jupyter lab build
-```
-
-To watch the files and build continuously:
-
-```bash
-jlpm build --watch # leave this running...
-jupyter lab --watch # ...in another terminal
-```
-
-To check and fix code style:
-
-```bash
-jlpm lint
-```
+### Getting the latest alpha/beta/RC version
-To run test the suite:
+Use `install` command (update does not seem to work) appending `@<0.x.y.rc-z>` to the
+extension name, like this:
```bash
-jlpm test
+jupyter labextension install @krassowski/jupyterlab-lsp@0.7.0-rc.0
```
## Acknowledgements
-This would not be possible if not the fantastic work at [wylieconlon/lsp-editor-adapter](https://github.com/wylieconlon/lsp-editor-adapter).
+This would not be possible without the fantastic initial work at
+[wylieconlon/lsp-editor-adapter](https://github.com/wylieconlon/lsp-editor-adapter).
diff --git a/RELEASE.md b/RELEASE.md
index 1c8541a21..0164b1e8f 100644
--- a/RELEASE.md
+++ b/RELEASE.md
@@ -4,15 +4,21 @@ Releases may require building both the python package and nodejs packages.
## Updating Version Strings
-The version for PyPI must be updated in two places:
+Check the version strings across the various files:
-- `py_src/jupyter_lsp/_version.py`
+```bash
+python scripts/integrity.py
+```
+
+> TODO: create a `release.py` script
+
+The PyPI version must be updated in at least two places:
+
+- `py_src/jupyter_lsp/_version.py` (canonical)
- `azure-pipelines.yml`
-The version for npm must be updated in five places (TODO create a `release.sh` or `release.py` script):
+The npm version must be updated in at least three places
-- `package.json`
+- `packages/jupyterlab-lsp/package.json` (canonical)
- `azure-pipelines.yml`
-- `packages/jupyterlab-lsp/package.json`
- `packages/metapackage/package.json`
-- `README.md`
diff --git a/ROADMAP.md b/ROADMAP.md
new file mode 100644
index 000000000..c56b53399
--- /dev/null
+++ b/ROADMAP.md
@@ -0,0 +1,23 @@
+# Roadmap
+
+> If a feature you need is not on the lists above, please feel free to suggest it
+> by opening a new [issue](https://github.com/krassowski/jupyterlab-lsp/issues).
+
+## Front End
+
+- improved code navigation when there are multiple jump targets
+- autocompleter with documentation and sorting based on LSP suggestions
+- system of settings, including options:
+ - to enable aggressive autocompletion (like in hinterland)
+ - to change the verbosity of signature hints (whether to show documentation, number of lines to be shown)
+- "rename" action in notebooks
+- gutter with linter results (low priority)
+- use the kernel session for autocompletion in FileEditor if available (PR welcome)
+
+## Backend
+
+- release on `conda`
+- [#49](https://github.com/krassowski/jupyterlab-lsp/issues/49)
+ cookiecutter for pip-installable specs
+- add hook system to allow serverextensions/kernels to modify, inspect and
+ react to LSP messages
diff --git a/py_src/jupyter_lsp/README.md b/py_src/jupyter_lsp/README.md
index 0c6b80d11..acd53bc02 100644
--- a/py_src/jupyter_lsp/README.md
+++ b/py_src/jupyter_lsp/README.md
@@ -3,143 +3,17 @@
Multi-[Language Server][language-server] WebSocket proxy for your Jupyter
`notebook` or `lab` server. For Python 3.5+.
-See the parent of this repository, [jupyterlab-lsp](https://github.com/krassowski/jupyterlab-lsp) for the
-reference client implementation for [JupyterLab][].
+> See the parent of this repository,
+> [jupyterlab-lsp](https://github.com/krassowski/jupyterlab-lsp) for the
+> reference client implementation for [JupyterLab][].
-## Installing language servers
+# Language Servers
-`jupyter-lsp` does not come with any Language Servers! However, we will try to use
-them if they _are_ installed and we know about them (you can disable this behavior
-by configuring [`autodetect`](#autodetect)).
-
-Use a package manager to install a [language server][lsp-implementations]
-(also [this list][langserver]) from the tables below: these implementations are
-tested to work with `jupyter-lsp`.
-
-| language | `npm install (-g)`, or `yarn/jlpm add (-g)` |
-| ------------------------- | :-----------------------------------------: |
-| bash | `bash-language-server` |
-| css
less
sass | `vscode-css-languageserver-bin` |
-| docker | `dockerfile-language-server-nodejs` |
-| html | `vscode-html-languageserver-bin` |
-| javascript
typescript | `javascript-typescript-langserver` |
-| json | `vscode-json-languageserver-bin` |
-| markdown | `unified-language-server` |
-| yaml | `yaml-language-server` |
-
-| language | `conda install -c conda-forge` | language-specific package manager |
-| -------- | :----------------------------: | :-----------------------------------------------: |
-| python | `python-language-server` | `pip install python-language-server` |
-| r | `r-languageserver` | `Rscript -e 'install.packages("languageserver")'` |
+`jupyter-lsp` does not come with any Language Servers! Learn more about installing
+and configuring [language servers](../../LANGUAGESERVERS.md)
[language-server]: https://microsoft.github.io/language-server-protocol/specification
[langserver]: https://langserver.org
-[jupyter-server-proxy]: https://github.com/jupyterhub/jupyter-server-proxy
[lsp-implementations]: https://microsoft.github.io/language-server-protocol/implementors/servers
[jupyter-lsp]: https://github.com/krassowski/jupyterlab-lsp.git
[jupyterlab]: https://github.com/jupyterlab/jupyterlab
-
-Don't see an implementation for the language server you need? You can
-[bring your own language server](#adding-custom-language-servers).
-
-> Please consider [contributing your language server spec](./CONTRIBUTING.md#spec)
-> to `jupyter-lsp`!
-
-## Adding custom language servers
-
-### Jupyter config via `traitlets`
-
-Like the Jupyter Notebook server, JupyterHub and other Jupyter interactive computing
-tools, `jupyter-lsp` can be configured via [Python or JSON files][notebook-config]
-in _well-known locations_. You can find out where to put them on your system with:
-
-[notebook-config]: https://jupyter-notebook.readthedocs.io/en/stable/config.html
-
-```bash
-jupyter --paths
-```
-
-They will be merged from bottom to top, and the directory where you launch your
-`notebook` server wins, making it easy to check in to version control.
-
-```python
-# ./jupyter_notebook_config.json ---------- unique! -----------
-# | |
-# or e.g. V V
-# $PREFIX/etc/jupyter/jupyter_notebook_config.d/a-language-server-implementation.json
-{
- "LanguageServerManager": {
- "language_servers": {
- "a-language-server-implementation": {
- "argv": ["/absolute/path/to/a-language-server", "--stdio"],
- "languages": ["a-language"]
- }
- }
- }
-}
-```
-
-More complex configurations that can't be hard-coded may benefit from the python approach:
-
-```py
-# jupyter_notebook_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"]
- },
- "another-language-implementation": {
- # if run like a script
- "argv": [shutil.which("another-language-interpreter"), "another-language-server"],
- "languages": ["another-language"]
- }
-}
-```
-
-### Python `entry_points`
-
-`pip`-installable packages in the same environment as the Jupyter `notebook` server
-can be automatically detected as providing a language server spec. These are a
-little more involved: see [CONTRIBUTING](./CONTRIBUTING.md).
-
-# Configuration Options
-
-Like `language_servers`, these can be configured via `jupyter_notebook_config.json`
-(or .py) or via command line arguments to `jupyter notebook` or `jupyter lab`.
-
-## nodejs
-
-> default: autodetect
-
-A custom absolute path to your `nodejs` executable.
-
-## autodetect
-
-> default: True
-
-`jupyter-lsp` will look for all [known language servers](#installing-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 `node_modules`, such as `nodejs`-backed language servers.
-The order is, roughly:
-
-- the folder where `notebook` or `lab` was launched
-- the JupyterLab `staging` folder
-- wherever `conda` puts global node modules
-- wherever 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`
diff --git a/scripts/integrity.py b/scripts/integrity.py
index da6fa2934..7a77a5e80 100644
--- a/scripts/integrity.py
+++ b/scripts/integrity.py
@@ -101,13 +101,6 @@ def test_ts_package_integrity(name, info, the_meta_package):
jsonschema.validators.Draft7Validator(schema_instance)
-def test_ts_readme():
- version = PACKAGES[MAIN_NAME][1]["version"]
- assert (
- "{}@{}".format(MAIN_NAME, version) in MAIN_README.read_text()
- ), "README.md is out of sync vs {}".format(version)
-
-
@pytest.mark.parametrize(
"path",
map(