Skip to content

Commit db2dd2b

Browse files
committed
Allow to use Jedi language server in system environment or virtual environments
As this extension uses an internal Jedi LSP, it is hard for the users to change the jedi setting to adapt various requirements. And in some cases, the user require a specific version of the Jedi, which is hard to change as it is embedded. Add a new configuration property to allow the users to use Jedi LSP in their system environment or virtual environments, and auto fallback to the internal version if the external version is not found. Signed-off-by: Inochi Amaoto <inochiama@gmail.com>
1 parent e2681d5 commit db2dd2b

File tree

5 files changed

+39
-8
lines changed

5 files changed

+39
-8
lines changed

package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,12 @@
536536
"scope": "window",
537537
"type": "string"
538538
},
539+
"python.jedi.useJediInEnvPath": {
540+
"default": false,
541+
"description": "%python.jedi.useJediInEnvPath.description%",
542+
"scope": "window",
543+
"type": "boolean"
544+
},
539545
"python.interpreter.infoVisibility": {
540546
"default": "onPythonRelated",
541547
"description": "%python.interpreter.infoVisibility.description%",

package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"python.languageServer.jediDescription": "Use Jedi behind the Language Server Protocol (LSP) as a language server.",
5757
"python.languageServer.pylanceDescription": "Use Pylance as a language server.",
5858
"python.languageServer.noneDescription": "Disable language server capabilities.",
59+
"python.jedi.useJediInEnvPath.description": "Use Jedi in system environment (if pyenv is disabled) or virtual environments folder (if pyenv is enabled) instead of the builtin Jedi.",
5960
"python.interpreter.infoVisibility.description": "Controls when to display information of selected interpreter in the status bar.",
6061
"python.interpreter.infoVisibility.never.description": "Never display information.",
6162
"python.interpreter.infoVisibility.onPythonRelated.description": "Only display information if Python-related files are opened.",

python_files/run-jedi-language-server.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,21 @@
22
import pathlib
33
import sys
44

5-
# Add the lib path to our sys path so jedi_language_server can find its references
6-
extension_dir = pathlib.Path(__file__).parent.parent
7-
EXTENSION_ROOT = os.fsdecode(extension_dir)
8-
sys.path.insert(0, os.fsdecode(extension_dir / "python_files" / "lib" / "jedilsp"))
9-
del extension_dir
5+
use_external_jedi = os.getenv("USE_JEDI_IN_ENV", '0') == "1"
6+
7+
if use_external_jedi:
8+
try:
9+
import jedi_language_server
10+
except Exception:
11+
print("External Jedi is not found, fallback to the builtin one.", file=sys.stderr)
12+
use_external_jedi = False
13+
14+
if not use_external_jedi:
15+
# Add the lib path to our sys path so jedi_language_server can find its references
16+
extension_dir = pathlib.Path(__file__).parent.parent
17+
EXTENSION_ROOT = os.fsdecode(extension_dir)
18+
sys.path.insert(0, os.fsdecode(extension_dir / "python_files" / "lib" / "jedilsp"))
19+
del extension_dir
1020

1121

1222
from jedi_language_server.cli import cli # noqa: E402

src/client/activation/jedi/languageClientFactory.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
// Licensed under the MIT License.
33

44
import * as path from 'path';
5-
import { LanguageClient, LanguageClientOptions, ServerOptions } from 'vscode-languageclient/node';
5+
import { WorkspaceConfiguration } from 'vscode';
6+
import { ExecutableOptions, LanguageClient, LanguageClientOptions, ServerOptions } from 'vscode-languageclient/node';
67

78
import { EXTENSION_ROOT_DIR, PYTHON_LANGUAGE } from '../../common/constants';
89
import { Resource } from '../../common/types';
@@ -13,7 +14,10 @@ import { ILanguageClientFactory } from '../types';
1314
const languageClientName = 'Python Jedi';
1415

1516
export class JediLanguageClientFactory implements ILanguageClientFactory {
16-
constructor(private interpreterService: IInterpreterService) {}
17+
constructor(
18+
private interpreterService: IInterpreterService,
19+
private readonly workspaceConfiguration: WorkspaceConfiguration,
20+
) {}
1721

1822
public async createLanguageClient(
1923
resource: Resource,
@@ -23,9 +27,16 @@ export class JediLanguageClientFactory implements ILanguageClientFactory {
2327
// Just run the language server using a module
2428
const lsScriptPath = path.join(EXTENSION_ROOT_DIR, 'python_files', 'run-jedi-language-server.py');
2529
const interpreter = await this.interpreterService.getActiveInterpreter(resource);
30+
const useJediInEnv = this.workspaceConfiguration.get<boolean>('jedi.useJediInEnvPath') === true;
31+
const envVars: NodeJS.ProcessEnv = {
32+
USE_JEDI_IN_ENV: useJediInEnv ? '1' : '0',
33+
...process.env,
34+
};
35+
const executableOptions: ExecutableOptions = { env: envVars };
2636
const serverOptions: ServerOptions = {
2737
command: interpreter ? interpreter.path : 'python',
2838
args: [lsScriptPath],
39+
options: executableOptions,
2940
};
3041

3142
return new LanguageClient(PYTHON_LANGUAGE, languageClientName, serverOptions, clientOptions);

src/client/languageServer/jediLSExtensionManager.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,10 @@ export class JediLSExtensionManager implements IDisposable, ILanguageServerExten
4747
configurationService,
4848
workspaceService,
4949
);
50-
this.clientFactory = new JediLanguageClientFactory(interpreterService);
50+
this.clientFactory = new JediLanguageClientFactory(
51+
interpreterService,
52+
workspaceService.getConfiguration('python'),
53+
);
5154
this.serverProxy = new JediLanguageServerProxy(this.clientFactory);
5255
this.serverManager = new JediLanguageServerManager(
5356
serviceContainer,

0 commit comments

Comments
 (0)