-
Notifications
You must be signed in to change notification settings - Fork 43
/
server.ts
126 lines (113 loc) · 4.43 KB
/
server.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import * as fsapi from 'fs-extra';
import { Disposable, env, LogOutputChannel } from 'vscode';
import { State } from 'vscode-languageclient';
import {
LanguageClient,
LanguageClientOptions,
RevealOutputChannelOn,
ServerOptions,
} from 'vscode-languageclient/node';
import { DEBUG_SERVER_SCRIPT_PATH, SERVER_SCRIPT_PATH } from './constants';
import { traceError, traceInfo, traceVerbose } from './log/logging';
import { getDebuggerPath } from './python';
import { getExtensionSettings, getGlobalSettings, getWorkspaceSettings, ISettings } from './settings';
import { getLSClientTraceLevel, getProjectRoot } from './utilities';
import { isVirtualWorkspace } from './vscodeapi';
export type IInitOptions = { settings: ISettings[]; globalSettings: ISettings };
async function createServer(
settings: ISettings,
serverId: string,
serverName: string,
outputChannel: LogOutputChannel,
initializationOptions: IInitOptions,
): Promise<LanguageClient> {
const command = settings.interpreter[0];
const cwd = settings.cwd;
// Set debugger path needed for debugging python code.
const newEnv = { ...process.env };
const debuggerPath = await getDebuggerPath();
const isDebugScript = await fsapi.pathExists(DEBUG_SERVER_SCRIPT_PATH);
if (newEnv.USE_DEBUGPY && debuggerPath) {
newEnv.DEBUGPY_PATH = debuggerPath;
} else {
newEnv.USE_DEBUGPY = 'False';
}
// Set import strategy
newEnv.LS_IMPORT_STRATEGY = settings.importStrategy;
// Set notification type
newEnv.LS_SHOW_NOTIFICATION = settings.showNotifications;
const args =
newEnv.USE_DEBUGPY === 'False' || !isDebugScript
? settings.interpreter.slice(1).concat([SERVER_SCRIPT_PATH])
: settings.interpreter.slice(1).concat([DEBUG_SERVER_SCRIPT_PATH]);
traceInfo(`Server run command: ${[command, ...args].join(' ')}`);
const serverOptions: ServerOptions = {
command,
args,
options: { cwd, env: newEnv },
};
// Options to control the language client
const clientOptions: LanguageClientOptions = {
// Register the server for python documents
documentSelector: isVirtualWorkspace()
? [{ language: 'python' }]
: [
{ scheme: 'file', language: 'python' },
{ scheme: 'untitled', language: 'python' },
{ scheme: 'vscode-notebook', language: 'python' },
{ scheme: 'vscode-notebook-cell', language: 'python' },
],
outputChannel: outputChannel,
traceOutputChannel: outputChannel,
revealOutputChannelOn: RevealOutputChannelOn.Never,
initializationOptions,
};
return new LanguageClient(serverId, serverName, serverOptions, clientOptions);
}
let _disposables: Disposable[] = [];
export async function restartServer(
serverId: string,
serverName: string,
outputChannel: LogOutputChannel,
lsClient?: LanguageClient,
): Promise<LanguageClient | undefined> {
if (lsClient) {
traceInfo(`Server: Stop requested`);
await lsClient.stop();
_disposables.forEach((d) => d.dispose());
_disposables = [];
}
const projectRoot = await getProjectRoot();
const workspaceSetting = await getWorkspaceSettings(serverId, projectRoot, true);
const newLSClient = await createServer(workspaceSetting, serverId, serverName, outputChannel, {
settings: await getExtensionSettings(serverId, true),
globalSettings: await getGlobalSettings(serverId, false),
});
traceInfo(`Server: Start requested.`);
_disposables.push(
newLSClient.onDidChangeState((e) => {
switch (e.newState) {
case State.Stopped:
traceVerbose(`Server State: Stopped`);
break;
case State.Starting:
traceVerbose(`Server State: Starting`);
break;
case State.Running:
traceVerbose(`Server State: Running`);
break;
}
}),
);
try {
await newLSClient.start();
} catch (ex) {
traceError(`Server: Start failed: ${ex}`);
return undefined;
}
const level = getLSClientTraceLevel(outputChannel.logLevel, env.logLevel);
await newLSClient.setTrace(level);
return newLSClient;
}