Skip to content

Commit 69e3209

Browse files
committed
First Connect
1 parent d617194 commit 69e3209

File tree

4 files changed

+76
-26
lines changed

4 files changed

+76
-26
lines changed

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1011,12 +1011,12 @@
10111011
"verbose"
10121012
],
10131013
"default": "off",
1014-
"markdownDescription": "Traces the communication between VS Code and the PowerShell Editor Services [LSP Server](https://microsoft.github.io/language-server-protocol/). **only for extension developers and issue troubleshooting!**"
1014+
"markdownDescription": "Traces the communication between VS Code and the PowerShell Editor Services [LSP Server](https://microsoft.github.io/language-server-protocol/). **Only for extension developers and issue troubleshooting!**"
10151015
},
10161016
"powershell.trace.dap": {
10171017
"type": "boolean",
10181018
"default": false,
1019-
"markdownDescription": "Traces the communication between VS Code and the PowerShell Editor Services [DAP Server](https://microsoft.github.io/debug-adapter-protocol/). **This setting is only meant for extension developers and issue troubleshooting!**"
1019+
"markdownDescription": "Traces the communication between VS Code and the PowerShell Editor Services [DAP Server](https://microsoft.github.io/debug-adapter-protocol/). **Only meant for extension developers and issue troubleshooting!**"
10201020
}
10211021
}
10221022
},

src/features/DebugSession.ts

+18-14
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import { PowerShellProcess } from "../process";
3737
import { IEditorServicesSessionDetails, SessionManager } from "../session";
3838
import { getSettings } from "../settings";
3939
import path from "path";
40-
import { checkIfFileExists } from "../utils";
40+
import { checkIfFileExists, onPowerShellSettingChange } from "../utils";
4141

4242
export const StartDebuggerNotificationType =
4343
new NotificationType<void>("powerShell/startDebugger");
@@ -608,17 +608,9 @@ class PowerShellDebugAdapterTrackerFactory implements DebugAdapterTrackerFactory
608608
disposables: Disposable[] = [];
609609
dapLogEnabled: boolean = workspace.getConfiguration("powershell").get<boolean>("trace.dap") ?? false;
610610
constructor(private adapterName = "PowerShell") {
611-
this.disposables.push(workspace.onDidChangeConfiguration(change => {
612-
if (
613-
change.affectsConfiguration("powershell.trace.dap")
614-
) {
615-
this.dapLogEnabled = workspace.getConfiguration("powershell").get<boolean>("trace.dap") ?? false;
616-
if (this.dapLogEnabled) {
617-
// Trigger the output pane to appear. This gives the user time to position it before starting a debug.
618-
this.log?.show(true);
619-
}
620-
}
621-
}));
611+
this.disposables.push(
612+
onPowerShellSettingChange("trace.dap", (visible:boolean | undefined) => {this.setLogVisibility(visible);})
613+
);
622614
}
623615

624616
/* We want to use a shared output log for separate debug sessions as usually only one is running at a time and we
@@ -630,10 +622,20 @@ class PowerShellDebugAdapterTrackerFactory implements DebugAdapterTrackerFactory
630622
_log: LogOutputChannel | undefined;
631623
get log(): LogOutputChannel | undefined {
632624
if (this.dapLogEnabled && this._log === undefined) {
633-
this._log = window.createOutputChannel(`${this.adapterName} Trace - DAP`, { log: true });
625+
this._log = window.createOutputChannel(`${this.adapterName}: Trace DAP`, { log: true });
634626
this.disposables.push(this._log);
635627
}
636-
return this.dapLogEnabled ? this._log : undefined;
628+
return this._log;
629+
}
630+
631+
private setLogVisibility(visible?: boolean): void {
632+
if (this.log !== undefined) {
633+
if (visible) {
634+
this.log.show(true);
635+
} else {
636+
this.log.hide();
637+
}
638+
}
637639
}
638640

639641
createDebugAdapterTracker(session: DebugSession): DebugAdapterTracker {
@@ -663,6 +665,8 @@ class PowerShellDebugAdapterTrackerFactory implements DebugAdapterTrackerFactory
663665
};
664666
}
665667

668+
669+
666670
dispose(): void {
667671
this.disposables.forEach(d => d.dispose());
668672
}

src/session.ts

+23-2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,20 @@ export class SessionManager implements Middleware {
9494
private suppressRestartPrompt = false;
9595
private versionDetails: IPowerShellVersionDetails | undefined;
9696

97+
private _outputChannel?: vscode.LogOutputChannel;
98+
/** Omnisharp and PSES messages sent via LSP are surfaced here. */
99+
private get outputChannel(): vscode.LogOutputChannel {
100+
return this._outputChannel
101+
??= vscode.window.createOutputChannel("PowerShell: Editor Services", { log: true });
102+
}
103+
104+
private _traceOutputChannel?: vscode.LogOutputChannel;
105+
/** The LanguageClient LSP message trace is surfaced here. */
106+
private get traceOutputChannel(): vscode.LogOutputChannel {
107+
return this._traceOutputChannel
108+
??= vscode.window.createOutputChannel("PowerShell: Trace LSP", { log: true });
109+
}
110+
97111
constructor(
98112
private extensionContext: vscode.ExtensionContext,
99113
private sessionSettings: Settings,
@@ -131,13 +145,16 @@ export class SessionManager implements Middleware {
131145
this.HostVersion = this.HostVersion.split("-")[0];
132146

133147
this.registerCommands();
148+
134149
}
135150

151+
136152
public async dispose(): Promise<void> {
137153
await this.stop(); // A whole lot of disposals.
138154

139155
this.languageStatusItem.dispose();
140156

157+
141158
for (const handler of this.registeredHandlers) {
142159
handler.dispose();
143160
}
@@ -622,6 +639,7 @@ export class SessionManager implements Middleware {
622639
});
623640
});
624641
};
642+
625643
const clientOptions: LanguageClientOptions = {
626644
documentSelector: this.documentSelector,
627645
synchronize: {
@@ -645,9 +663,11 @@ export class SessionManager implements Middleware {
645663
// hangs up (ECONNRESET errors).
646664
error: (_error: Error, _message: Message, _count: number): ErrorHandlerResult => {
647665
// TODO: Is there any error worth terminating on?
666+
this.logger.writeError(`${_error.name}: ${_error.message} ${_error.cause}`);
648667
return { action: ErrorAction.Continue };
649668
},
650669
closed: (): CloseHandlerResult => {
670+
this.logger.write("Language service connection closed.");
651671
// We have our own restart experience
652672
return {
653673
action: CloseAction.DoNotRestart,
@@ -656,8 +676,8 @@ export class SessionManager implements Middleware {
656676
},
657677
},
658678
middleware: this,
659-
traceOutputChannel: vscode.window.createOutputChannel("PowerShell Trace - LSP", {log: true}),
660-
outputChannel: vscode.window.createOutputChannel("PowerShell Editor Services", {log: true}),
679+
traceOutputChannel: this.traceOutputChannel,
680+
outputChannel: this.outputChannel
661681
};
662682

663683
const languageClient = new LanguageClient("powershell", "PowerShell Editor Services Client", connectFunc, clientOptions);
@@ -666,6 +686,7 @@ export class SessionManager implements Middleware {
666686
// TODO: We should only turn this on in preview.
667687
languageClient.registerProposedFeatures();
668688

689+
669690
// NOTE: We don't currently send any events from PSES, but may again in
670691
// the future so we're leaving this side wired up.
671692
languageClient.onTelemetry((event) => {

src/utils.ts

+33-8
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,11 @@ export function sleep(ms: number): Promise<void> {
8787
}
8888

8989
/**
90-
* Invokes the specified action when a PowerShell setting changes
91-
* @param setting a string representation of the setting you wish to evaluate
90+
* Invokes the specified action when a setting changes
91+
* @param setting a string representation of the setting you wish to evaluate, e.g. `trace.server`
9292
* @param action the action to take when the setting changes
93-
* @param scope the scope in which the vscode setting should be evaluated. Defaults to
93+
* @param section the section of the vscode settings to evaluate. Defaults to `powershell`
94+
* @param scope the scope in which the vscode setting should be evaluated.
9495
* @param workspace
9596
* @param onDidChangeConfiguration
9697
* @example onPowerShellSettingChange("settingName", (newValue) => console.log(newValue));
@@ -99,19 +100,43 @@ export function sleep(ms: number): Promise<void> {
99100

100101
// Because we actually do use the constraint in the callback
101102
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
102-
export function onPowerShellSettingChange<T>(
103+
export function onSettingChange<T>(
104+
section: string,
103105
setting: string,
104-
listener: (newValue: T | undefined) => void,
105-
section: "powershell",
106+
action: (newValue: T | undefined) => void,
106107
scope?: vscode.ConfigurationScope,
107108
): vscode.Disposable {
109+
const settingPath = `${section}.${setting}`;
108110
return vscode.workspace.onDidChangeConfiguration(e => {
109-
if (!e.affectsConfiguration(section, scope)) { return; }
111+
if (!e.affectsConfiguration(settingPath, scope)) { return; }
110112
const value = vscode.workspace.getConfiguration(section, scope).get<T>(setting);
111-
listener(value);
113+
action(value);
112114
});
113115
}
114116

117+
/**
118+
* Invokes the specified action when a PowerShell setting changes. Convenience function for `onSettingChange`
119+
* @param setting a string representation of the setting you wish to evaluate, e.g. `trace.server`
120+
* @param action the action to take when the setting changes
121+
* @param section the section of the vscode settings to evaluate. Defaults to `powershell`
122+
* @param scope the scope in which the vscode setting should be evaluated.
123+
* @param workspace
124+
* @param onDidChangeConfiguration
125+
* @example onPowerShellSettingChange("settingName", (newValue) => console.log(newValue));
126+
* @returns a Disposable object that can be used to stop listening for changes
127+
*/
128+
129+
// Because we actually do use the constraint in the callback
130+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
131+
export function onPowerShellSettingChange<T>(
132+
setting: string,
133+
action: (newValue: T | undefined) => void,
134+
scope?: vscode.ConfigurationScope,
135+
): vscode.Disposable {
136+
const section = "powershell";
137+
return onSettingChange(section, setting, action, scope);
138+
}
139+
115140
export const isMacOS: boolean = process.platform === "darwin";
116141
export const isWindows: boolean = process.platform === "win32";
117142
export const isLinux: boolean = !isMacOS && !isWindows;

0 commit comments

Comments
 (0)