Skip to content

Commit

Permalink
Updating to the latest extension template.
Browse files Browse the repository at this point in the history
  • Loading branch information
karthiknadig committed Mar 28, 2023
1 parent e6ce660 commit 96e6fad
Show file tree
Hide file tree
Showing 14 changed files with 344 additions and 176 deletions.
2 changes: 1 addition & 1 deletion bundled/tool/lsp_jsonrpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ def __init__(self):
self._lock = threading.Lock()
self._thread_pool = ThreadPoolExecutor(10)

@atexit.register
def stop_all_processes(self):
"""Send exit command to all processes and shutdown transport."""
for i in self._rpc.values():
Expand Down Expand Up @@ -175,6 +174,7 @@ def get_json_rpc(self, workspace: str) -> JsonRpc:


_process_manager = ProcessManager()
atexit.register(_process_manager.stop_all_processes)


def _get_json_rpc(workspace: str) -> Union[JsonRpc, None]:
Expand Down
88 changes: 55 additions & 33 deletions bundled/tool/lsp_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import pathlib
import sys
import traceback
from typing import Any, Dict, List, Sequence, Union
from typing import Any, Dict, List, Optional, Sequence, Union


# **********************************************************
Expand Down Expand Up @@ -41,6 +41,7 @@ def update_sys_path(path_to_add: str, strategy: str) -> None:
from pygls import protocol, server, uris, workspace

WORKSPACE_SETTINGS = {}
GLOBAL_SETTINGS = {}
RUNNER = pathlib.Path(__file__).parent / "lsp_runner.py"

MAX_WORKERS = 5
Expand Down Expand Up @@ -185,33 +186,35 @@ def initialize(params: lsp.InitializeParams) -> None:
"""LSP handler for initialize request."""
log_to_output(f"CWD Server: {os.getcwd()}")

paths = "\r\n ".join(sys.path)
log_to_output(f"sys.path used to run Server:\r\n {paths}")
GLOBAL_SETTINGS.update(**params.initialization_options.get("globalSettings", {}))

settings = params.initialization_options["settings"]
_update_workspace_settings(settings)
log_to_output(
f"Settings used to run Server:\r\n{json.dumps(settings, indent=4, ensure_ascii=False)}\r\n"
)
log_to_output(
f"Global settings:\r\n{json.dumps(GLOBAL_SETTINGS, indent=4, ensure_ascii=False)}\r\n"
)

paths = "\r\n ".join(sys.path)
log_to_output(f"sys.path used to run Server:\r\n {paths}")

if isinstance(LSP_SERVER.lsp, protocol.LanguageServerProtocol):
if any(setting["logLevel"] == "debug" for setting in settings):
LSP_SERVER.lsp.trace = lsp.TraceValues.Verbose
elif any(
setting["logLevel"] in ["error", "warn", "info"] for setting in settings
):
LSP_SERVER.lsp.trace = lsp.TraceValues.Messages
else:
LSP_SERVER.lsp.trace = lsp.TraceValues.Off
_log_version_info()


@LSP_SERVER.feature(lsp.EXIT)
def on_exit():
def on_exit(_params: Optional[Any] = None) -> None:
"""Handle clean up on exit."""
jsonrpc.shutdown_json_rpc()


@LSP_SERVER.feature(lsp.SHUTDOWN)
def on_shutdown(_params: Optional[Any] = None) -> None:
"""Handle clean up on shutdown."""
jsonrpc.shutdown_json_rpc()


def _log_version_info() -> None:
for value in WORKSPACE_SETTINGS.values():
try:
Expand Down Expand Up @@ -261,18 +264,24 @@ def _log_version_info() -> None:
# *****************************************************
# Internal functional and settings management APIs.
# *****************************************************
def _get_global_defaults():
return {
"path": GLOBAL_SETTINGS.get("path", []),
"interpreter": GLOBAL_SETTINGS.get("interpreter", [sys.executable]),
"args": GLOBAL_SETTINGS.get("args", []),
"importStrategy": GLOBAL_SETTINGS.get("importStrategy", "useBundled"),
"showNotifications": GLOBAL_SETTINGS.get("showNotifications", "off"),
}


def _update_workspace_settings(settings):
if not settings:
key = os.getcwd()
WORKSPACE_SETTINGS[key] = {
"cwd": key,
"workspaceFS": key,
"workspace": uris.from_fs_path(key),
"logLevel": "error",
"path": [],
"interpreter": [sys.executable],
"args": [],
"importStrategy": "useBundled",
"showNotifications": "off",
**_get_global_defaults(),
}
return

Expand All @@ -284,14 +293,30 @@ def _update_workspace_settings(settings):
}


def _get_document_key(document: workspace.Document):
document_workspace = pathlib.Path(document.path)
def _get_settings_by_path(file_path: pathlib.Path):
workspaces = {s["workspaceFS"] for s in WORKSPACE_SETTINGS.values()}

while document_workspace != document_workspace.parent:
if str(document_workspace) in workspaces:
return str(document_workspace)
document_workspace = document_workspace.parent
while file_path != file_path.parent:
str_file_path = str(file_path)
if str_file_path in workspaces:
return WORKSPACE_SETTINGS[str_file_path]
file_path = file_path.parent

setting_values = list(WORKSPACE_SETTINGS.values())
return setting_values[0]


def _get_document_key(document: workspace.Document):
if WORKSPACE_SETTINGS:
document_workspace = pathlib.Path(document.path)
workspaces = {s["workspaceFS"] for s in WORKSPACE_SETTINGS.values()}

# Find workspace settings for the given file.
while document_workspace != document_workspace.parent:
if str(document_workspace) in workspaces:
return str(document_workspace)
document_workspace = document_workspace.parent

return None


Expand All @@ -301,16 +326,13 @@ def _get_settings_by_document(document: workspace.Document | None):

key = _get_document_key(document)
if key is None:
# This is either a non-workspace file or there is no workspace.
key = os.fspath(pathlib.Path(document.path).parent)
return {
"cwd": key,
"workspaceFS": key,
"workspace": uris.from_fs_path(key),
"logLevel": "error",
"path": [],
"interpreter": [sys.executable],
"args": [],
"importStrategy": "useBundled",
"showNotifications": "off",
**_get_global_defaults(),
}

return WORKSPACE_SETTINGS[str(key)]
Expand Down Expand Up @@ -342,7 +364,7 @@ def _run_tool_on_document(
settings = copy.deepcopy(_get_settings_by_document(document))

code_workspace = settings["workspaceFS"]
cwd = settings["workspaceFS"]
cwd = settings["cwd"]

use_path = False
use_rpc = False
Expand Down Expand Up @@ -422,7 +444,7 @@ def _run_tool_on_document(
def _run_tool(extra_args: Sequence[str], settings: Dict[str, Any]) -> utils.RunResult:
"""Runs tool."""
code_workspace = settings["workspaceFS"]
cwd = settings["workspaceFS"]
cwd = settings["cwd"]

use_path = False
use_rpc = False
Expand Down
20 changes: 0 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,26 +71,6 @@
],
"configuration": {
"properties": {
"black-formatter.logLevel": {
"default": "error",
"description": "%settings.logLevel.description%",
"enum": [
"debug",
"error",
"info",
"off",
"warn"
],
"scope": "window",
"type": "string",
"enumDescriptions": [
"%settings.logLevel.debug.description%",
"%settings.logLevel.error.description%",
"%settings.logLevel.info.description%",
"%settings.logLevel.off.description%",
"%settings.logLevel.warn.description%"
]
},
"black-formatter.args": {
"default": [],
"description": "%settings.args.description%",
Expand Down
6 changes: 0 additions & 6 deletions package.nls.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
{
"extension.description": "Formatting support for python files using `black`.",
"command.restartServer": "Restart Server",
"settings.logLevel.description": "The trace level the extension logs at, defaults to 'error'.",
"settings.logLevel.debug.description": "Includes verbose logging intended for debugging purposes.",
"settings.logLevel.error.description": "Only errors and always logged information.",
"settings.logLevel.info.description": "Includes all messages that are not marked as verbose or debug.",
"settings.logLevel.off.description": "Most logging is turned off, any information that is always logged might still be shown.",
"settings.logLevel.warn.description": "Includes all messages in the error category and any additional warnings.",
"settings.args.description": "Arguments passed in. Each argument is a separate string in the array.",
"settings.path.description": "When set to a path to `black` binary, extension will use that for linting. NOTE: Using this option may slowdown linting.",
"settings.importStrategy.description": "Defines where `black` is imported from. This setting may be ignored if `black-formatter.path` is set.",
Expand Down
60 changes: 60 additions & 0 deletions src/common/logging.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

import * as util from 'util';
import { Disposable, LogOutputChannel } from 'vscode';

type Arguments = unknown[];
class OutputChannelLogger {
constructor(private readonly channel: LogOutputChannel) {}

public traceLog(...data: Arguments): void {
this.channel.appendLine(util.format(...data));
}

public traceError(...data: Arguments): void {
this.channel.error(util.format(...data));
}

public traceWarn(...data: Arguments): void {
this.channel.warn(util.format(...data));
}

public traceInfo(...data: Arguments): void {
this.channel.info(util.format(...data));
}

public traceVerbose(...data: Arguments): void {
this.channel.debug(util.format(...data));
}
}

let channel: OutputChannelLogger | undefined;
export function registerLogger(logChannel: LogOutputChannel): Disposable {
channel = new OutputChannelLogger(logChannel);
return {
dispose: () => {
channel = undefined;
},
};
}

export function traceLog(...args: Arguments): void {
channel?.traceLog(...args);
}

export function traceError(...args: Arguments): void {
channel?.traceError(...args);
}

export function traceWarn(...args: Arguments): void {
channel?.traceWarn(...args);
}

export function traceInfo(...args: Arguments): void {
channel?.traceInfo(...args);
}

export function traceVerbose(...args: Arguments): void {
channel?.traceVerbose(...args);
}
5 changes: 2 additions & 3 deletions src/common/nullFormatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
// Licensed under the MIT License.

import { Disposable } from 'vscode';
import { traceLog } from './log/logging';
import { getDocumentSelector } from './utilities';
import { registerDocumentFormattingEditProvider } from './vscodeapi';
import { traceLog } from './logging';
import { getDocumentSelector, registerDocumentFormattingEditProvider } from './vscodeapi';

let disposables: Disposable[] = [];
export function registerEmptyFormatter(): void {
Expand Down
20 changes: 18 additions & 2 deletions src/common/python.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

/* eslint-disable @typescript-eslint/naming-convention */
import { commands, Disposable, Event, EventEmitter, extensions, Uri, WorkspaceFolder } from 'vscode';
import { traceError, traceLog } from './log/logging';
import { traceError, traceLog } from './logging';

type Environment = EnvironmentPath & {
/**
Expand Down Expand Up @@ -253,12 +253,17 @@ export async function initializePython(disposables: Disposable[]): Promise<void>
}
}

export async function resolveInterpreter(interpreter: string[]): Promise<ResolvedEnvironment | undefined> {
const api = await getPythonExtensionAPI();
return api?.environments.resolveEnvironment(interpreter[0]);
}

export async function getInterpreterDetails(resource?: Uri): Promise<IInterpreterDetails> {
const api = await getPythonExtensionAPI();
const environment = await api?.environments.resolveEnvironment(
api?.environments.getActiveEnvironmentPath(resource),
);
if (environment?.executable.uri) {
if (environment?.executable.uri && checkVersion(environment)) {
return { path: [environment?.executable.uri.fsPath], resource };
}
return { path: undefined, resource };
Expand All @@ -273,3 +278,14 @@ export async function runPythonExtensionCommand(command: string, ...rest: any[])
await activateExtension();
return await commands.executeCommand(command, ...rest);
}

export function checkVersion(resolved: ResolvedEnvironment | undefined): boolean {
const version = resolved?.version;
if (version?.major === 3 && version?.minor >= 7) {
return true;
}
traceError(`Python version ${version?.major}.${version?.minor} is not supported.`);
traceError(`Selected python path: ${resolved?.executable.uri?.fsPath}`);
traceError('Supported versions are 3.7 and above.');
return false;
}
Loading

0 comments on commit 96e6fad

Please sign in to comment.