Skip to content

Commit

Permalink
Merge pull request #587 from yuntan/pr-add-spec-pyright
Browse files Browse the repository at this point in the history
add Pyright langserver spec
  • Loading branch information
krassowski authored May 23, 2021
2 parents 080f772 + 252a8dc commit 76f59d5
Show file tree
Hide file tree
Showing 16 changed files with 111 additions and 21 deletions.
11 changes: 6 additions & 5 deletions .github/workflows/job.test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -214,15 +214,16 @@ jobs:
include:
# if using 3.6, use an old node
- python: 3.6
# Node 10 end-of-life: April 2021
nodejs: '>=10,<11.0.0.a0'
# if using 3.7, use newer node, etc...
- python: 3.7
# Node 12 end-of-life: April 2022
nodejs: '>=12,<13.0.0.a0'
- python: 3.8
# if using 3.7, use newer node, etc...
- python: 3.7
# Node 14 end-of-life: April 2023
nodejs: '>=14,<15.0.0.a0'
- python: 3.8
# TODO: switch to Node 16 once gets merged https://github.com/conda-forge/nodejs-feedstock/pull/189
# Node 15 end-of-life: June 2021
nodejs: '>=15,<16.0.0.a0'
# TODO: remove when mambaforge just works on setup-miniconda
- os: ubuntu
mambaforge: Linux-x86_64.sh
Expand Down
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@

- 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)

- bug fixes:
- workaround url-parse issue causing problems when using JupyterLab 3.0.15 [#599]

- 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])

[#586]: https://github.com/krassowski/jupyterlab-lsp/pull/586
[#587]: https://github.com/krassowski/jupyterlab-lsp/pull/587
[#588]: https://github.com/krassowski/jupyterlab-lsp/pull/588
[#599]: https://github.com/krassowski/jupyterlab-lsp/pull/599

Expand Down
14 changes: 12 additions & 2 deletions atest/01_Editor.robot
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,13 @@ Less
Markdown
Editor Shows Features for Language Markdown example.md Diagnostics=`Color` is misspelt

Python
Python (pylsp)
${def} = Set Variable xpath:(//span[contains(@class, 'cm-variable')][contains(text(), 'fib')])[last()]
Editor Shows Features for Language Python example.py Diagnostics=multiple spaces after keyword Jump to Definition=${def} Rename=${def}
Editor Shows Features for Server pylsp Python example.py Diagnostics=undefined name 'result' (pyflakes) Jump to Definition=${def} Rename=${def}

Python (pyright)
${def} = Set Variable xpath:(//span[contains(@class, 'cm-variable')][contains(text(), 'fib')])[last()]
Editor Shows Features for Server pyright Python example.py Diagnostics=is not defined (Pyright) Jump to Definition=${def}

R
${def} = Set Variable xpath:(//span[contains(@class, 'cm-variable')][contains(text(), 'fib')])[last()]
Expand All @@ -70,6 +74,12 @@ YAML
Editor Shows Features for Language YAML example.yaml Diagnostics=duplicate key

*** Keywords ***
Editor Shows Features for Server
[Arguments] ${server} ${Language} ${file} &{features}
Configure JupyterLab Plugin
... {"language_servers": {"${server}": {"priority": 10000}}}
Editor Shows Features for Language ${Language} ${file} &{features}

Editor Shows Features for Language
[Arguments] ${Language} ${file} &{features}
Prepare File for Editing ${Language} editor ${file}
Expand Down
1 change: 1 addition & 0 deletions atest/Keywords.robot
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ Configure JupyterLab Plugin
Set Editor Content ${settings json} ${CSS USER SETTINGS}
Wait Until Page Contains No errors found
Click Element css:button[title\='Save User Settings']
Wait Until Page Contains No errors found
Click Element ${JLAB XP CLOSE SETTINGS}

Clean Up After Working with File and Settings
Expand Down
4 changes: 2 additions & 2 deletions atest/examples/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from itertools import (accumulate, chain); accumulate


# fibs :: Integer :: [Integer]
def fibs(n):
'''An accumulation of the first n integers in
Expand All @@ -27,5 +26,6 @@ def go(ab, _):
print(
'First twenty: ' + repr(
fibs(20)
)
),
result
)
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"npm-run-all": "^4.1.5",
"precise-commits": "^1.0.2",
"prettier": "^2.1.2",
"pyright": "^1.1",
"sql-language-server": "^0.11.4",
"typescript": "~4.1.3",
"unified-language-server": "^0.3.0",
Expand Down
8 changes: 7 additions & 1 deletion packages/jupyterlab-lsp/schema/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,13 @@
"language_servers": {
"title": "Language Server",
"description": "Language-server specific configuration, keyed by implementation, e.g: \n\npyls: {\n serverSettings: {\n pyls: {\n plugins: {\n pydocstyle: {\n enabled: true\n },\n pyflakes: {\n enabled: false\n },\n flake8: {\n enabled: true\n }\n }\n }\n }\n}\n\nAlternatively, using VSCode's naming convention:\n\npyls: {\n serverSettings: {\n \"pyls.plugins.pydocstyle.enabled\": true,\n \"pyls.plugins.pyflakes.enabled\": false,\n \"pyls.plugins.flake8.enabled\": true\n }\n}",
"default": {},
"default": {
"pyright": {
"serverSettings": {
"python.analysis.useLibraryCodeForTypes": true
}
}
},
"patternProperties": {
".*": {
"$ref": "#/definitions/language-server"
Expand Down
22 changes: 17 additions & 5 deletions packages/jupyterlab-lsp/src/connection_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,16 +162,28 @@ export class DocumentConnectionManager {
}

/**
* Currently only supports the settings that the language servers
* accept using onDidChangeConfiguration messages, under the
* "serverSettings" keyword in the setting registry. New keywords can
* be added and extra functionality implemented here when needed.
* Handles the settings that do not require an existing connection
* with a language server (or can influence to which server the
* connection will be created, e.g. `priority`).
*
* This function should be called **before** initialization of servers.
*/
public updateConfiguration(allServerSettings: TLanguageServerConfigurations) {
this.language_server_manager.setConfiguration(allServerSettings);
}

/**
* Handles the settings that the language servers accept using
* `onDidChangeConfiguration` messages, which should be passed under
* the "serverSettings" keyword in the setting registry.
* Other configuration options are handled by `updateConfiguration` instead.
*
* This function should be called **after** initialization of servers.
*/
public updateServerConfigurations(
allServerSettings: TLanguageServerConfigurations
) {
let language_server_id: TServerKeys;
this.language_server_manager.setConfiguration(allServerSettings);

for (language_server_id in allServerSettings) {
if (!allServerSettings.hasOwnProperty(language_server_id)) {
Expand Down
11 changes: 9 additions & 2 deletions packages/jupyterlab-lsp/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,11 @@ export class LSPExtension implements ILSPExtension {
.then(settings => {
// Store the initial server settings, to be sent asynchronously
// when the servers are initialized.
this.connection_manager.initial_configurations = (settings.composite
.language_servers || {}) as TLanguageServerConfigurations;
const initial_configuration = (settings.composite.language_servers ||
{}) as TLanguageServerConfigurations;
this.connection_manager.initial_configurations = initial_configuration;
// update the server-independent part of configuration immediately
this.connection_manager.updateConfiguration(initial_configuration);

settings.changed.connect(() => {
this.updateOptions(settings);
Expand Down Expand Up @@ -223,6 +226,10 @@ export class LSPExtension implements ILSPExtension {

const languageServerSettings = (options.language_servers ||
{}) as TLanguageServerConfigurations;

this.connection_manager.initial_configurations = languageServerSettings;
// TODO: if priorities changed reset connections
this.connection_manager.updateConfiguration(languageServerSettings);
this.connection_manager.updateServerConfigurations(languageServerSettings);
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/jupyterlab-lsp/src/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export class LanguageServerManager implements ILanguageServerManager {
}
}

return matchingSessionsKeys.sort(this._comparePriorities);
return matchingSessionsKeys.sort(this._comparePriorities.bind(this));
}

get statusCode(): number {
Expand Down
13 changes: 13 additions & 0 deletions packages/jupyterlab-lsp/src/utils.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { expect } from 'chai';

import { uris_equal } from './utils';

describe('uris_equal', () => {
it('should workaround Windows paths/Pyright issues', () => {
const result = uris_equal(
'file:///d%3A/a/jupyterlab-lsp/jupyterlab-lsp/atest/output/windows_39_4/home/n%C3%B6te%20b%C3%B2%C3%B3ks/example.py',
'file:///d:/a/jupyterlab-lsp/jupyterlab-lsp/atest/output/windows_39_4/home/n%C3%B6te%20b%C3%B2%C3%B3ks/example.py'
);
expect(result).to.equal(true);
});
});
8 changes: 6 additions & 2 deletions packages/jupyterlab-lsp/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { PageConfig } from '@jupyterlab/coreutils';
import { ReadonlyJSONObject, ReadonlyJSONValue } from '@lumino/coreutils';
import mergeWith from 'lodash.mergewith';

const RE_PATH_ANCHOR = /^file:\/\/([^\/]+|\/[A-Z]:)/;
const RE_PATH_ANCHOR = /^file:\/\/([^\/]+|\/[a-zA-Z](?::|%3A))/;

export async function sleep(timeout: number) {
return new Promise<void>(resolve => {
Expand Down Expand Up @@ -142,7 +142,11 @@ export function is_win_path(uri: string) {
* lowercase the drive component of a URI
*/
export function normalize_win_path(uri: string) {
return uri.replace(RE_PATH_ANCHOR, it => it.toLowerCase());
// Pyright encodes colon on Windows, see:
// https://github.com/krassowski/jupyterlab-lsp/pull/587#issuecomment-844225253
return uri.replace(RE_PATH_ANCHOR, it =>
it.replace('%3A', ':').toLowerCase()
);
}

export function uri_to_contents_path(child: string, parent?: string) {
Expand Down
2 changes: 2 additions & 0 deletions python_packages/jupyter_lsp/jupyter_lsp/specs/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from .jedi_language_server import JediLanguageServer
from .julia_language_server import JuliaLanguageServer
from .pyls import PalantirPythonLanguageServer
from .pyright import PyrightLanguageServer
from .python_lsp_server import PythonLSPServer
from .r_languageserver import RLanguageServer
from .sql_language_server import SQLLanguageServer
Expand All @@ -28,6 +29,7 @@
md = UnifiedLanguageServer()
py_palantir = PalantirPythonLanguageServer()
py_lsp_server = PythonLSPServer()
pyright = PyrightLanguageServer()
r = RLanguageServer()
tex = Texlab()
ts = JavascriptTypescriptLanguageServer()
Expand Down
21 changes: 21 additions & 0 deletions python_packages/jupyter_lsp/jupyter_lsp/specs/pyright.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from .utils import NodeModuleSpec


class PyrightLanguageServer(NodeModuleSpec):
node_module = key = "pyright"
script = ["langserver.index.js"]
args = ["--stdio"]
languages = ["python"]
spec = dict(
display_name=key,
mime_types=["text/python", "text/x-ipython"],
urls=dict(
home="https://github.com/microsoft/pyright",
issues="https://github.com/microsoft/pyright/issues",
),
install=dict(
npm="npm install --save-dev {}".format(key),
yarn="yarn add --dev {}".format(key),
jlpm="jlpm add --dev {}".format(key),
),
)
1 change: 1 addition & 0 deletions python_packages/jupyter_lsp/setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ jupyter_lsp_spec_v1 =
julia-language-server = jupyter_lsp.specs:julia
python-language-server = jupyter_lsp.specs:py_palantir
python-lsp-server = jupyter_lsp.specs:py_lsp_server
pyright = jupyter_lsp.specs:pyright
r-languageserver = jupyter_lsp.specs:r
texlab = jupyter_lsp.specs:tex
sql-language-server = jupyter_lsp.specs:sql
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11445,6 +11445,11 @@ puppeteer@^1.17.0:
rimraf "^2.6.1"
ws "^6.1.0"

pyright@^1.1:
version "1.1.140"
resolved "https://registry.yarnpkg.com/pyright/-/pyright-1.1.140.tgz#2692f67b2769e664983dff3fefee4c0e4d12f4fa"
integrity sha512-isJj7cahjEK7xAy5/aLJ4TfzLJGA4SCWqPk1pLJA3k8S6VUo4FIiPrvHOd1LM2gxImqgef4rwUeHRC+vrOKLRQ==

q@^1.5.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
Expand Down

0 comments on commit 76f59d5

Please sign in to comment.