Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Julia and Jedi server auto-detection #481

Merged
merged 17 commits into from Jan 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 8 additions & 3 deletions .github/workflows/job.test.yml
Expand Up @@ -62,13 +62,13 @@ jobs:
installer-url: ${{ env.MAMBAFORGE_URL }}-Linux-x86_64.sh
condarc-file: .github/.condarc

- name: install base conda dependencies
- name: Install base conda dependencies
run: mamba env update -n test --file requirements/github-actions.yml

- name: install linting dependencies
- name: Install linting dependencies
run: mamba env update -n test --file requirements/lint.yml

- name: check integrity of package versions
- name: Check integrity of package versions
run: python scripts/integrity.py

- name: Cache node_modules
Expand Down Expand Up @@ -228,6 +228,11 @@ jobs:
steps:
- uses: actions/checkout@v2

- uses: julia-actions/setup-julia@v1

- name: Install Julia language server
run: julia -e 'using Pkg; Pkg.add("LanguageServer")'

- name: Set JupyterLab and Node versions
uses: cschleiden/replace-tokens@v1
with:
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,7 @@

- features

- added experimental detection of Julia and Jedi language servers ([#481])
- 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])
Expand All @@ -21,6 +22,7 @@
[#476]: https://github.com/krassowski/jupyterlab-lsp/pull/476
[#478]: https://github.com/krassowski/jupyterlab-lsp/pull/478
[#480]: https://github.com/krassowski/jupyterlab-lsp/pull/480
[#481]: https://github.com/krassowski/jupyterlab-lsp/pull/481

### `jupyter-lsp 1.0.1` (unreleased)

Expand Down
6 changes: 6 additions & 0 deletions CONTRIBUTING.md
Expand Up @@ -439,3 +439,9 @@ 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:

```robot
Configure JupyterLab Plugin {"loggingConsole": "floating", "loggingLevel": "debug"}
```
5 changes: 5 additions & 0 deletions atest/01_Editor.robot
Expand Up @@ -27,6 +27,9 @@ JSON
JSX
${def} = Set Variable xpath:(//span[contains(@class, 'cm-variable')][contains(text(), 'hello')])[last()]
Editor Shows Features for Language JSX example.jsx Diagnostics=Expression expected Jump to Definition=${def} Rename=${def}
#Julia
# ${def} = Set Variable xpath:(//span[contains(@class, 'cm-builtin')][contains(text(), 'add_together')])[last()]
# Editor Shows Features for Language Julia example.jl Jump to Definition=${def} Rename=${def}

LaTeX
[Tags] language:latex
Expand Down Expand Up @@ -70,7 +73,9 @@ YAML
Editor Shows Features for Language
[Arguments] ${Language} ${file} &{features}
Prepare File for Editing ${Language} editor ${file}
# Run Keyword If "${Language}" == "Julia" Sleep 35s
Wait Until Fully Initialized
# Run Keyword If "${Language}" == "Julia" Sleep 5s
FOR ${f} IN @{features}
Run Keyword If "${f}" == "Diagnostics" Editor Should Show Diagnostics ${features["${f}"]}
... ELSE IF "${f}" == "Jump to Definition" Editor Should Jump To Definition ${features["${f}"]}
Expand Down
1 change: 1 addition & 0 deletions atest/03_Notebook.robot
Expand Up @@ -68,5 +68,6 @@ Code Overrides
Setup Notebook Python ${file}
${virtual_path} = Set Variable ${VIRTUALDOCS DIR}${/}Code overrides.ipynb
Wait Until Created ${virtual_path}
Wait Until Keyword Succeeds 10x 1s File Should Not Be Empty ${virtual_path}
${document} = Get File ${virtual_path}
Should Be Equal ${document} get_ipython().run_line_magic("ls", "")\n\n\nget_ipython().run_line_magic("pip", " freeze")\n
1 change: 1 addition & 0 deletions atest/04_Interface/BackendFailure.robot
@@ -1,5 +1,6 @@
*** Settings ***
Suite Setup Setup Server and Browser server_extension_enabled=${False}
Suite Teardown Setup Server and Browser server_extension_enabled=${True}
Resource ../Keywords.robot

*** Variables ***
Expand Down
5 changes: 3 additions & 2 deletions atest/05_Features/Completion.robot
Expand Up @@ -223,7 +223,7 @@ Completes Large Namespaces
[Setup] Prepare File for Editing R completion completion.R
Place Cursor In File Editor At 6 7
Wait Until Fully Initialized
Trigger Completer
Wait Until Keyword Succeeds 3x 2s Trigger Completer timeout=45s
Completer Should Suggest abs timeout=30s
[Teardown] Clean Up After Working With File completion.R

Expand Down Expand Up @@ -272,5 +272,6 @@ Completer Should Not Suggest
Wait Until Page Does Not Contain Element ${COMPLETER_BOX} .jp-Completer-item[data-value="${text}"]

Trigger Completer
[Arguments] ${timeout}=35s
Press Keys None TAB
Wait Until Page Contains Element ${COMPLETER_BOX} timeout=35s
Wait Until Page Contains Element ${COMPLETER_BOX} timeout=${timeout}
3 changes: 2 additions & 1 deletion atest/05_Features/Highlights.robot
Expand Up @@ -45,14 +45,15 @@ Highlights are modified after typing
Should Highlight Token testa

Highlights are removed when no cell is focused
Enter Cell Editor 1 line=2
# Remove when turned on
Configure JupyterLab Plugin {"removeOnBlur": true} plugin id=${HIGHLIGHTS PLUGIN ID}
Enter Cell Editor 1 line=2
Should Highlight Token test
Blur Cell Editor 1
Should Not Highlight Any Tokens
# Do not remove when turned off
Configure JupyterLab Plugin {"removeOnBlur": false} plugin id=${HIGHLIGHTS PLUGIN ID}
Enter Cell Editor 1 line=2
Should Highlight Token test
Blur Cell Editor 1
Should Highlight Token test
Expand Down
1 change: 1 addition & 0 deletions atest/05_Features/Jump.robot
Expand Up @@ -16,6 +16,7 @@ Python Jumps between Files
Jump To Definition ${sel}
Wait Until Page Contains ANOTHER_CONSTANT
Capture Page Screenshot 10-jumped.png
Clean Up After Working With File jump_b.py

Ctrl Click And Jumping Back Works
[Setup] Prepare File for Editing Python editor jump.py
Expand Down
4 changes: 4 additions & 0 deletions atest/examples/example.jl
@@ -0,0 +1,4 @@
add_together(x,y) = x + y


add_together(1)
11 changes: 7 additions & 4 deletions docs/Language Servers.ipynb
Expand Up @@ -121,7 +121,10 @@
"source": [
"### Notebook-Optimized Language Servers\n",
"\n",
"These servers have well-tested support for notebooks and file editors."
"These servers have support for notebooks and file editors. The `pyls` and\n",
"`r-languageserver` are well-tested, while `jedi` and `Julia` servers are\n",
"experimental. Please only install one language server per language (`jedi` or\n",
"`pyls` for Python - not both)."
]
},
{
Expand All @@ -132,7 +135,7 @@
},
"outputs": [],
"source": [
"nb_langs = [\"pyls\", \"r-languageserver\"]\n",
"nb_langs = [\"pyls\", \"r-languageserver\", \"julia-language-server\", \"jedi-language-server\"]\n",
"lang_server_table(\n",
" {key: spec for key, spec in mgr.language_servers.items() if key in nb_langs}\n",
")"
Expand Down Expand Up @@ -207,7 +210,7 @@
" yaml-language-server\n",
"```\n",
"\n",
"This will create create (or add to):\n",
"This will create (or add to):\n",
"\n",
"- `package.json` (check this in!)\n",
"- `yarn.lock` (check this in!)\n",
Expand Down Expand Up @@ -255,7 +258,7 @@
"- `tectonic`, a cross-platform $\\LaTeX$ processing tool\n",
" - note, it will download a large number of packages when first executed\n",
"- `texlab`, a Language Server for `.tex` files that supports completion and\n",
" refernce navigation\n",
" reference navigation\n",
"- `chktex`, a `.tex` style checker"
]
},
Expand Down
4 changes: 4 additions & 0 deletions python_packages/jupyter_lsp/jupyter_lsp/specs/__init__.py
Expand Up @@ -5,6 +5,8 @@
from .bash_language_server import BashLanguageServer
from .dockerfile_language_server_nodejs import DockerfileLanguageServerNodeJS
from .javascript_typescript_langserver import JavascriptTypescriptLanguageServer
from .jedi_language_server import JediLanguageServer
from .julia_language_server import JuliaLanguageServer
from .pyls import PythonLanguageServer
from .r_languageserver import RLanguageServer
from .sql_language_server import SQLLanguageServer
Expand All @@ -19,7 +21,9 @@
css = VSCodeCSSLanguageServer()
dockerfile = DockerfileLanguageServerNodeJS()
html = VSCodeHTMLLanguageServer()
jedi = JediLanguageServer()
json = VSCodeJSONLanguageServer()
julia = JuliaLanguageServer()
md = UnifiedLanguageServer()
py = PythonLanguageServer()
r = RLanguageServer()
Expand Down
@@ -0,0 +1,19 @@
from .utils import ShellSpec


class JediLanguageServer(ShellSpec):
key = cmd = "jedi-language-server"
languages = ["python"]
spec = dict(
display_name="jedi-language-server",
mime_types=["text/python", "text/x-ipython"],
urls=dict(
home="https://github.com/pappasam/jedi-language-server",
issues="https://github.com/pappasam/jedi-language-server/issues",
),
install=dict(
pip="pip install -U jedi-language-server",
conda="conda install -c conda-forge jedi-language-server",
),
env=dict(PYTHONUNBUFFERED="1"),
)
@@ -0,0 +1,26 @@
from .utils import ShellSpec


class JuliaLanguageServer(ShellSpec):
key = "julia-language-server"
languages = ["julia"]
cmd = "julia"
args = [
"--project=.",
"-e",
"using LanguageServer, LanguageServer.SymbolServer; runserver()",
".",
]
is_installed_args = [
"-e",
'print(if (Base.find_package("LanguageServer") === nothing) "" else "yes" end)',
]
spec = dict(
display_name="LanguageServer.jl",
mime_types=["text/julia", "text/x-julia", "application/julia"],
urls=dict(
home="https://github.com/julia-vscode/LanguageServer.jl",
issues="https://github.com/julia-vscode/LanguageServer.jl/issues",
),
install=dict(julia='using Pkg; Pkg.add("LanguageServer")'),
)
1 change: 1 addition & 0 deletions python_packages/jupyter_lsp/jupyter_lsp/stdio.py
Expand Up @@ -113,6 +113,7 @@ def _read_content(self, length: int, max_parts=1000) -> Optional[bytes]:
1 part is usually sufficent but not enough for some long
messages 2 or 3 parts are often needed.
"""
raw = None
raw_parts: List[bytes] = []
received_size = 0
while received_size < length and len(raw_parts) < max_parts:
Expand Down
7 changes: 6 additions & 1 deletion python_packages/jupyter_lsp/jupyter_lsp/tests/conftest.py
Expand Up @@ -30,6 +30,8 @@
CMD_BASED_SERVERS = {
"Rscript": ["r-languageserver"],
"texlab": ["texlab"],
"jedi-language-server": ["jedi-language-server"],
"julia": ["julia-language-server"],
}

KNOWN_SERVERS += sum(
Expand Down Expand Up @@ -71,7 +73,10 @@ def jsonrpc_init_msg():
"jsonrpc": "2.0",
"method": "initialize",
"params": {
"capabilities": {},
"capabilities": {
# LanguageServer.jl assumes that it is not missing
"workspace": {"didChangeConfiguration": {}}
},
"initializationOptions": None,
"processId": None,
"rootUri": pathlib.Path(__file__).parent.as_uri(),
Expand Down
Expand Up @@ -91,7 +91,7 @@ async def all_listener(
all_listened.get(),
return_exceptions=True,
),
20,
120 if known_server == "julia-language-server" else 20,
)
assert all([isinstance(res, dict) for res in results])

Expand Down
Expand Up @@ -39,7 +39,10 @@ async def test_start_known(known_server, handlers, jsonrpc_init_msg):
await ws_handler.on_message(jsonrpc_init_msg)

try:
await asyncio.wait_for(ws_handler._messages_wrote.get(), 20)
await asyncio.wait_for(
ws_handler._messages_wrote.get(),
120 if known_server == "julia-language-server" else 20,
)
ws_handler._messages_wrote.task_done()
finally:
ws_handler.on_close()
Expand Down
2 changes: 2 additions & 0 deletions python_packages/jupyter_lsp/setup.cfg
Expand Up @@ -34,6 +34,8 @@ jupyter_lsp_spec_v1 =
bash-language-server = jupyter_lsp.specs:bash
dockerfile-language-server-nodejs = jupyter_lsp.specs:dockerfile
javascript-typescript-langserver = jupyter_lsp.specs:ts
jedi-language-server = jupyter_lsp.specs:jedi
julia-language-server = jupyter_lsp.specs:julia
python-language-server = jupyter_lsp.specs:py
r-languageserver = jupyter_lsp.specs:r
texlab = jupyter_lsp.specs:tex
Expand Down