Add restart LSP command to VSCode extension (#4916)

This PR adds a new command to the Carbon VSCode extension "carbon:
Restart language server" which acts similar to clangd / bazel
extensions. While not useful during regular working of the extension
this helps when LSP either crashes or the toolchain is updated.

In order to support graceful restart, I needed to add a Call handler for
"shutdown" which is noop for now. Lsp clients always call shutdown
before sending exit.

---------

Co-authored-by: jonmeow <jperkins@google.com>
This commit is contained in:
DavidLoftus
2025-02-10 23:39:49 +00:00
committed by GitHub
co-authored by jonmeow
parent 063b9d8ca9
commit 2eddfbd7bf
17 changed files with 287 additions and 15 deletions
+6
View File
@@ -39,6 +39,12 @@ auto HandleInitialize(
llvm::function_ref<void(llvm::Expected<llvm::json::Object>)> on_done)
-> void;
// Prepares LSP for shutdown.
auto HandleShutdown(
Context& /*context*/,
const clang::clangd::NoParams& /*client_capabilities*/,
llvm::function_ref<void(llvm::Expected<std::nullptr_t>)> on_done) -> void;
} // namespace Carbon::LanguageServer
#endif // CARBON_TOOLCHAIN_LANGUAGE_SERVER_HANDLE_H_
@@ -0,0 +1,21 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#include "toolchain/language_server/handle.h"
namespace Carbon::LanguageServer {
auto HandleShutdown(
Context& /*context*/,
const clang::clangd::NoParams& /*client_capabilities*/,
llvm::function_ref<void(llvm::Expected<std::nullptr_t>)> on_done) -> void {
// TODO: Track that `shutdown` was called, and:
// - Warn on duplicate calls.
// - Make `exit` return `1` if `shutdown` wasn't called.
// https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#exit
// - Error on other post-`shutdown` calls.
on_done(nullptr);
}
} // namespace Carbon::LanguageServer
@@ -74,6 +74,7 @@ IncomingMessages::IncomingMessages(clang::clangd::Transport* transport,
: transport_(transport), context_(context) {
AddCallHandler("textDocument/documentSymbol", &HandleDocumentSymbol);
AddCallHandler("initialize", &HandleInitialize);
AddCallHandler("shutdown", &HandleShutdown);
AddNotificationHandler("textDocument/didChange",
&HandleDidChangeTextDocument);
AddNotificationHandler("textDocument/didClose", &HandleDidCloseTextDocument);
@@ -0,0 +1,35 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// AUTOUPDATE
// TIP: To test this file alone, run:
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/language_server/testdata/basics/fail_shutdown_without_exit.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/language_server/testdata/basics/fail_shutdown_without_exit.carbon
// --- STDIN
[[@LSP-CALL:initialize]]
[[@LSP-CALL:shutdown]]
// --- AUTOUPDATE-SPLIT
// CHECK:STDERR: error: Input/output error [LanguageServerTransportError]
// CHECK:STDERR:
// CHECK:STDOUT: Content-Length: 146{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 1,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": {
// CHECK:STDOUT: "capabilities": {
// CHECK:STDOUT: "documentSymbolProvider": true,
// CHECK:STDOUT: "textDocumentSync": 1
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }Content-Length: 51{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 2,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": null
// CHECK:STDOUT: }
@@ -10,6 +10,7 @@
// --- STDIN
[[@LSP-CALL:initialize]]
[[@LSP-CALL:shutdown]]
[[@LSP-NOTIFY:exit]]
// --- AUTOUPDATE-SPLIT
@@ -25,4 +26,10 @@
// CHECK:STDOUT: "textDocumentSync": 1
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }Content-Length: 51{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 2,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": null
// CHECK:STDOUT: }
@@ -10,11 +10,30 @@
// --- STDIN
[[@LSP-CALL:initialize]]
[[@LSP-NOTIFY:textDocument/didOpen:"nope": "bad"]]
[[@LSP-CALL:shutdown]]
[[@LSP-NOTIFY:exit]]
// --- AUTOUPDATE-SPLIT
// CHECK:STDERR: warning: -32602: in call to `textDocument/didOpen`, JSON parse failed: missing value at (root).textDocument [LanguageServerNotificationParseError]
// CHECK:STDERR:
// CHECK:STDOUT:
// CHECK:STDOUT: Content-Length: 146{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 1,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": {
// CHECK:STDOUT: "capabilities": {
// CHECK:STDOUT: "documentSymbolProvider": true,
// CHECK:STDOUT: "textDocumentSync": 1
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }Content-Length: 51{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 2,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": null
// CHECK:STDOUT: }
@@ -9,6 +9,7 @@
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/language_server/testdata/document_symbol/basics.carbon
// --- STDIN
[[@LSP-CALL:initialize]]
[[@LSP-NOTIFY:textDocument/didOpen:
"textDocument": {"uri": "file:/empty.carbon", "languageId": "carbon",
"text": ""}
@@ -30,11 +31,23 @@
[[@LSP-CALL:textDocument/documentSymbol:
"textDocument": {"uri": "file:/fn.carbon"}
]]
[[@LSP-CALL:shutdown]]
[[@LSP-NOTIFY:exit]]
// --- AUTOUPDATE-SPLIT
// CHECK:STDOUT: Content-Length: 145{{\r}}
// CHECK:STDOUT: Content-Length: 146{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 1,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": {
// CHECK:STDOUT: "capabilities": {
// CHECK:STDOUT: "documentSymbolProvider": true,
// CHECK:STDOUT: "textDocumentSync": 1
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }Content-Length: 145{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "jsonrpc": "2.0",
@@ -46,7 +59,7 @@
// CHECK:STDOUT: }Content-Length: 49{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 1,
// CHECK:STDOUT: "id": 2,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": []
// CHECK:STDOUT: }Content-Length: 147{{\r}}
@@ -61,7 +74,7 @@
// CHECK:STDOUT: }Content-Length: 49{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 2,
// CHECK:STDOUT: "id": 3,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": []
// CHECK:STDOUT: }Content-Length: 142{{\r}}
@@ -76,7 +89,7 @@
// CHECK:STDOUT: }Content-Length: 459{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 3,
// CHECK:STDOUT: "id": 4,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": [
// CHECK:STDOUT: {
@@ -104,4 +117,10 @@
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: ]
// CHECK:STDOUT: }Content-Length: 51{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 5,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": null
// CHECK:STDOUT: }
@@ -9,13 +9,32 @@
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/language_server/testdata/document_symbol/language.carbon
// --- STDIN
[[@LSP-CALL:initialize]]
[[@LSP-CALL:textDocument/documentSymbol:
"textDocument": {"uri": "file:/test.cpp"}
]]
[[@LSP-CALL:shutdown]]
[[@LSP-NOTIFY:exit]]
// --- AUTOUPDATE-SPLIT
// CHECK:STDERR: /test.cpp: warning: non-Carbon file requested [LanguageServerFileUnsupported]
// CHECK:STDERR:
// CHECK:STDOUT:
// CHECK:STDOUT: Content-Length: 146{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 1,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": {
// CHECK:STDOUT: "capabilities": {
// CHECK:STDOUT: "documentSymbolProvider": true,
// CHECK:STDOUT: "textDocumentSync": 1
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }Content-Length: 51{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 3,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": null
// CHECK:STDOUT: }
@@ -9,13 +9,32 @@
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/language_server/testdata/document_symbol/unknown.carbon
// --- STDIN
[[@LSP-CALL:initialize]]
[[@LSP-CALL:textDocument/documentSymbol:
"textDocument": {"uri": "file:/test.carbon"}
]]
[[@LSP-CALL:shutdown]]
[[@LSP-NOTIFY:exit]]
// --- AUTOUPDATE-SPLIT
// CHECK:STDERR: /test.carbon: warning: unknown file requested [LanguageServerFileUnknown]
// CHECK:STDERR:
// CHECK:STDOUT:
// CHECK:STDOUT: Content-Length: 146{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 1,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": {
// CHECK:STDOUT: "capabilities": {
// CHECK:STDOUT: "documentSymbolProvider": true,
// CHECK:STDOUT: "textDocumentSync": 1
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }Content-Length: 51{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 3,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": null
// CHECK:STDOUT: }
@@ -9,6 +9,7 @@
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/language_server/testdata/text_document/change_count.carbon
// --- STDIN
[[@LSP-CALL:initialize]]
[[@LSP-NOTIFY:textDocument/didOpen:
"textDocument": {"uri": "file:/test.carbon", "languageId": "carbon",
"text": "// Empty"}
@@ -28,6 +29,7 @@
"text": "a"}
]
]]
[[@LSP-CALL:shutdown]]
[[@LSP-NOTIFY:exit]]
// --- AUTOUPDATE-SPLIT
@@ -36,7 +38,18 @@
// CHECK:STDERR:
// CHECK:STDERR: /test.carbon: warning: received unsupported contentChanges count: 2 [LanguageServerUnsupportedChanges]
// CHECK:STDERR:
// CHECK:STDOUT: Content-Length: 144{{\r}}
// CHECK:STDOUT: Content-Length: 146{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 1,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": {
// CHECK:STDOUT: "capabilities": {
// CHECK:STDOUT: "documentSymbolProvider": true,
// CHECK:STDOUT: "textDocumentSync": 1
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }Content-Length: 144{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "jsonrpc": "2.0",
@@ -45,4 +58,10 @@
// CHECK:STDOUT: "diagnostics": [],
// CHECK:STDOUT: "uri": "file:///test.carbon"
// CHECK:STDOUT: }
// CHECK:STDOUT: }Content-Length: 51{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 2,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": null
// CHECK:STDOUT: }
@@ -9,14 +9,33 @@
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/language_server/testdata/text_document/change_unknown.carbon
// --- STDIN
[[@LSP-CALL:initialize]]
[[@LSP-NOTIFY:textDocument/didChange:
"textDocument": {"uri": "file:/test.carbon"},
"contentChanges": [{"text": "new content"}]
]]
[[@LSP-CALL:shutdown]]
[[@LSP-NOTIFY:exit]]
// --- AUTOUPDATE-SPLIT
// CHECK:STDERR: /test.carbon: warning: unknown file requested [LanguageServerFileUnknown]
// CHECK:STDERR:
// CHECK:STDOUT:
// CHECK:STDOUT: Content-Length: 146{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 1,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": {
// CHECK:STDOUT: "capabilities": {
// CHECK:STDOUT: "documentSymbolProvider": true,
// CHECK:STDOUT: "textDocumentSync": 1
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }Content-Length: 51{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 2,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": null
// CHECK:STDOUT: }
@@ -9,13 +9,32 @@
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/language_server/testdata/text_document/close_unknown.carbon
// --- STDIN
[[@LSP-CALL:initialize]]
[[@LSP-NOTIFY:textDocument/didClose:
"textDocument": {"uri": "file:/test.carbon"}
]]
[[@LSP-CALL:shutdown]]
[[@LSP-NOTIFY:exit]]
// --- AUTOUPDATE-SPLIT
// CHECK:STDERR: /test.carbon: warning: tried closing unknown file; ignoring request [LanguageServerCloseUnknownFile]
// CHECK:STDERR:
// CHECK:STDOUT:
// CHECK:STDOUT: Content-Length: 146{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 1,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": {
// CHECK:STDOUT: "capabilities": {
// CHECK:STDOUT: "documentSymbolProvider": true,
// CHECK:STDOUT: "textDocumentSync": 1
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }Content-Length: 51{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 2,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": null
// CHECK:STDOUT: }
@@ -9,6 +9,7 @@
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/language_server/testdata/text_document/diagnostics.carbon
// --- STDIN
[[@LSP-CALL:initialize]]
[[@LSP-NOTIFY:textDocument/didOpen:
"textDocument": {"uri": "file:/test.carbon", "languageId": "carbon",
"version": 1, "text": "{"}
@@ -20,11 +21,23 @@
[[@LSP-NOTIFY:textDocument/didClose:
"textDocument": {"uri": "file:/test.carbon"}
]]
[[@LSP-CALL:shutdown]]
[[@LSP-NOTIFY:exit]]
// --- AUTOUPDATE-SPLIT
// CHECK:STDOUT: Content-Length: 1164{{\r}}
// CHECK:STDOUT: Content-Length: 146{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 1,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": {
// CHECK:STDOUT: "capabilities": {
// CHECK:STDOUT: "documentSymbolProvider": true,
// CHECK:STDOUT: "textDocumentSync": 1
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }Content-Length: 1164{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "jsonrpc": "2.0",
@@ -106,4 +119,10 @@
// CHECK:STDOUT: "uri": "file:///test.carbon",
// CHECK:STDOUT: "version": 2
// CHECK:STDOUT: }
// CHECK:STDOUT: }Content-Length: 51{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 2,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": null
// CHECK:STDOUT: }
@@ -9,6 +9,7 @@
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/language_server/testdata/text_document/open_change_close.carbon
// --- STDIN
[[@LSP-CALL:initialize]]
[[@LSP-NOTIFY:textDocument/didOpen:
"textDocument": {"uri": "file:/test.carbon", "languageId": "carbon",
"text": "// Empty"}
@@ -20,11 +21,23 @@
[[@LSP-NOTIFY:textDocument/didClose:
"textDocument": {"uri": "file:/test.carbon"}
]]
[[@LSP-CALL:shutdown]]
[[@LSP-NOTIFY:exit]]
// --- AUTOUPDATE-SPLIT
// CHECK:STDOUT: Content-Length: 144{{\r}}
// CHECK:STDOUT: Content-Length: 146{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 1,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": {
// CHECK:STDOUT: "capabilities": {
// CHECK:STDOUT: "documentSymbolProvider": true,
// CHECK:STDOUT: "textDocumentSync": 1
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }Content-Length: 144{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "jsonrpc": "2.0",
@@ -42,4 +55,10 @@
// CHECK:STDOUT: "diagnostics": [],
// CHECK:STDOUT: "uri": "file:///test.carbon"
// CHECK:STDOUT: }
// CHECK:STDOUT: }Content-Length: 51{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 2,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": null
// CHECK:STDOUT: }
@@ -9,6 +9,7 @@
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/language_server/testdata/text_document/open_duplicate.carbon
// --- STDIN
[[@LSP-CALL:initialize]]
[[@LSP-NOTIFY:textDocument/didOpen:
"textDocument": {"uri": "file:/test.carbon", "languageId": "carbon",
"text": "// Empty"}
@@ -17,13 +18,25 @@
"textDocument": {"uri": "file:/test.carbon", "languageId": "carbon",
"text": "// Empty"}
]]
[[@LSP-CALL:shutdown]]
[[@LSP-NOTIFY:exit]]
// --- AUTOUPDATE-SPLIT
// CHECK:STDERR: /test.carbon: warning: duplicate open file request; updating content [LanguageServerOpenDuplicateFile]
// CHECK:STDERR:
// CHECK:STDOUT: Content-Length: 144{{\r}}
// CHECK:STDOUT: Content-Length: 146{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 1,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": {
// CHECK:STDOUT: "capabilities": {
// CHECK:STDOUT: "documentSymbolProvider": true,
// CHECK:STDOUT: "textDocumentSync": 1
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT: }Content-Length: 144{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "jsonrpc": "2.0",
@@ -41,4 +54,10 @@
// CHECK:STDOUT: "diagnostics": [],
// CHECK:STDOUT: "uri": "file:///test.carbon"
// CHECK:STDOUT: }
// CHECK:STDOUT: }Content-Length: 51{{\r}}
// CHECK:STDOUT: {{\r}}
// CHECK:STDOUT: {
// CHECK:STDOUT: "id": 2,
// CHECK:STDOUT: "jsonrpc": "2.0",
// CHECK:STDOUT: "result": null
// CHECK:STDOUT: }
+7 -1
View File
@@ -46,7 +46,13 @@
"default": "./bazel-bin/toolchain/carbon"
}
}
}
},
"commands": [
{
"command": "carbon.lsp.restart",
"title": "carbon: Restart language server"
}
]
},
"scripts": {
"vscode:prepublish": "npm run package",
+7 -1
View File
@@ -8,7 +8,7 @@
* This is the main launcher for the LSP extension.
*/
import { workspace, ExtensionContext } from 'vscode';
import { workspace, ExtensionContext, commands } from 'vscode';
import {
LanguageClient,
@@ -43,6 +43,12 @@ export function activate(context: ExtensionContext) {
clientOptions
);
client.start();
context.subscriptions.push(
commands.registerCommand('carbon.lsp.restart', () => {
client.restart();
})
);
}
export function deactivate(): Thenable<void> | undefined {