diff --git a/CHANGELOG.md b/CHANGELOG.md
index 295e739b..fc616368 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,7 @@
- Add [`LTeX: Reset and Restart`](https://valentjn.github.io/vscode-ltex/docs/commands.html#ltex-reset-and-restart) command to reset the extension and restart LTEX LS (equivalent to reloading the VS Code window)
- Fix inconsistent titles of German commands
- Hide internal commands in table of keyboard shortcuts to prevent confusion (see [#282](https://github.com/valentjn/vscode-ltex/issues/282))
+- Engineering: A running instance of LTEX LS, if it has been started with `--server-type=tcpSocket`, will be chosen over starting a new instance; this enables simultaneous debugging of vscode-ltex and ltex-ls
- Update LTEX LS to 12.0.0
## 10.0.0 — “The Unicode Simulation” (April 5, 2021)
diff --git a/src/DependencyManager.ts b/src/DependencyManager.ts
index db80c264..2eecdba7 100644
--- a/src/DependencyManager.ts
+++ b/src/DependencyManager.ts
@@ -13,6 +13,7 @@ import extractZip from 'extract-zip';
import * as Fs from 'fs';
import * as Http from 'http';
import * as Https from 'https';
+import * as Net from 'net';
import * as Os from 'os';
import * as Path from 'path';
import * as SemVer from 'semver';
@@ -612,6 +613,38 @@ export default class DependencyManager {
return {command: ltexLsScriptPath, args: [], options: {'env': env}};
}
+ public static getDebugServerOptions(): CodeLanguageClient.ServerOptions | null {
+ const executableOptions: ChildProcess.SpawnSyncOptionsWithStringEncoding = {
+ encoding: 'utf-8',
+ timeout: 10000,
+ };
+ const childProcess: ChildProcess.SpawnSyncReturns = ((process.platform == 'win32')
+ ? ChildProcess.spawnSync('wmic', ['process', 'list', 'FULL'], executableOptions)
+ : ChildProcess.spawnSync('ps', ['-A', '-o', 'args'], executableOptions));
+ if (childProcess.status != 0) return null;
+ const output: string = childProcess.stdout;
+
+ const matchPos: number = output.search(
+ /LtexLanguageServerLauncher.*--server-type(?: +|=)tcpSocket/);
+ if (matchPos == -1) return null;
+ const startPos: number = output.lastIndexOf('\n', matchPos);
+ const endPos: number = output.indexOf('\n', matchPos);
+ const line: string = output.substring(((startPos != -1) ? startPos : 0),
+ ((endPos != -1) ? endPos : output.length));
+
+ const match: RegExpMatchArray | null = line.match(/--port(?: +|=)([0-9]+)/);
+ if (match == null) return null;
+ const port: number = parseInt(match[1]);
+ if (port == 0) return null;
+
+ const socket: Net.Socket = new Net.Socket();
+ socket.connect(port, 'localhost');
+
+ return () => {
+ return Promise.resolve({writer: socket, reader: socket});
+ };
+ }
+
public get vscodeLtexVersion(): string {
return this._vscodeLtexVersion;
}
diff --git a/src/extension.ts b/src/extension.ts
index 65b4be23..b9a2a01d 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -66,18 +66,24 @@ async function languageClientIsReady(languageClient: CodeLanguageClient.Language
async function startLanguageClient(context: Code.ExtensionContext,
externalFileManager: ExternalFileManager, statusPrinter: StatusPrinter):
Promise {
- if (dependencyManager == null) {
- Logger.error('DependencyManager not initialized!');
- return Promise.resolve(null);
+ let serverOptions: CodeLanguageClient.ServerOptions | null = null;
+
+ if (context.extensionMode == Code.ExtensionMode.Development) {
+ serverOptions = DependencyManager.getDebugServerOptions();
}
- const success: boolean = await dependencyManager.install();
- if (success !== true) return Promise.resolve(null);
+ if (serverOptions == null) {
+ if (dependencyManager == null) {
+ Logger.error('DependencyManager not initialized!');
+ return Promise.resolve(null);
+ }
- const statusBarItemManager: StatusBarItemManager = new StatusBarItemManager(context);
+ const success: boolean = await dependencyManager.install();
+ if (success !== true) return Promise.resolve(null);
+ serverOptions = await dependencyManager.getLtexLsExecutable();
+ }
- const serverOptions: CodeLanguageClient.ServerOptions =
- await dependencyManager.getLtexLsExecutable();
+ const statusBarItemManager: StatusBarItemManager = new StatusBarItemManager(context);
const workspaceConfig: Code.WorkspaceConfiguration = Code.workspace.getConfiguration('ltex');
const enabled: any = workspaceConfig.get('enabled');
@@ -123,9 +129,11 @@ async function startLanguageClient(context: Code.ExtensionContext,
null, languageClient, externalFileManager, statusBarItemManager));
statusPrinter.languageClient = languageClient;
- Logger.log(i18n('startingLtexLs'));
- Logger.logExecutable(serverOptions);
- Logger.log('');
+ if ('command' in serverOptions) {
+ Logger.log(i18n('startingLtexLs'));
+ Logger.logExecutable(serverOptions);
+ Logger.log('');
+ }
languageClient.info(i18n('startingLtexLs'));
const languageClientDisposable: Code.Disposable = languageClient.start();