Skip to content

Commit 5aaf0cc

Browse files
Add port provider (#85)
* Add port attribute provider * Add message * Enabled proposed api * Ignore all the ports * Fix format * fix pr comments * Add regex for terminal command * Add adapter to pattern
1 parent 4277963 commit 5aaf0cc

File tree

4 files changed

+127
-1
lines changed

4 files changed

+127
-1
lines changed

package.json

+3
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
"description": "Python Debugger extension using `debugpy`.",
55
"version": "2023.3.0-dev",
66
"publisher": "ms-python",
7+
"enabledApiProposals": [
8+
"portsAttributes"
9+
],
710
"license": "MIT",
811
"homepage": "https://github.com/Microsoft/vscode-python-debugger",
912
"repository": {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*---------------------------------------------------------
2+
* Copyright (C) Microsoft Corporation. All rights reserved.
3+
*--------------------------------------------------------*/
4+
5+
import { CancellationToken, PortAttributes, PortAttributesProvider, ProviderResult } from 'vscode';
6+
7+
export class DebugPortAttributesProvider implements PortAttributesProvider {
8+
public providePortAttributes(
9+
_attributes: { port: number; pid?: number; commandLine?: string },
10+
_token: CancellationToken,
11+
): ProviderResult<PortAttributes> {
12+
return undefined;
13+
}
14+
}

src/extension/extensionInit.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
'use strict';
55

6-
import { debug, DebugConfigurationProviderTriggerKind, languages, Uri, window } from 'vscode';
6+
import { debug, DebugConfigurationProviderTriggerKind, languages, Uri, window, workspace } from 'vscode';
77
import { executeCommand, getConfiguration, registerCommand, startDebugging } from './common/vscodeapi';
88
import { DebuggerTypeName } from './constants';
99
import { DynamicPythonDebugConfigurationService } from './debugger/configuration/dynamicdebugConfigurationService';
@@ -31,6 +31,7 @@ import { JsonLanguages, LaunchJsonCompletionProvider } from './debugger/configur
3131
import { LaunchJsonUpdaterServiceHelper } from './debugger/configuration/launch.json/updaterServiceHelper';
3232
import { ignoreErrors } from './common/promiseUtils';
3333
import { pickArgsInput } from './common/utils/localize';
34+
import { DebugPortAttributesProvider } from './debugger/debugPort/portAttributesProvider';
3435

3536
export async function registerDebugger(context: IExtensionContext): Promise<void> {
3637
const childProcessAttachService = new ChildProcessAttachService();
@@ -125,4 +126,12 @@ export async function registerDebugger(context: IExtensionContext): Promise<void
125126
launchJsonCompletionProvider,
126127
),
127128
);
129+
130+
const debugPortAttributesProvider = new DebugPortAttributesProvider();
131+
context.subscriptions.push(
132+
workspace.registerPortAttributesProvider(
133+
{ commandPattern: /extensions.ms-python.debugpy.*debugpy.(launcher|adapter)/ },
134+
debugPortAttributesProvider,
135+
),
136+
);
128137
}

vscode.proposed.portsAttributes.d.ts

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
declare module 'vscode' {
7+
8+
// https://github.com/microsoft/vscode/issues/115616 @alexr00
9+
10+
/**
11+
* The action that should be taken when a port is discovered through automatic port forwarding discovery.
12+
*/
13+
export enum PortAutoForwardAction {
14+
/**
15+
* Notify the user that the port is being forwarded. This is the default action.
16+
*/
17+
Notify = 1,
18+
/**
19+
* Once the port is forwarded, open the user's web browser to the forwarded port.
20+
*/
21+
OpenBrowser = 2,
22+
/**
23+
* Once the port is forwarded, open the preview browser to the forwarded port.
24+
*/
25+
OpenPreview = 3,
26+
/**
27+
* Forward the port silently.
28+
*/
29+
Silent = 4,
30+
/**
31+
* Do not forward the port.
32+
*/
33+
Ignore = 5
34+
}
35+
36+
/**
37+
* The attributes that a forwarded port can have.
38+
*/
39+
export class PortAttributes {
40+
/**
41+
* The action to be taken when this port is detected for auto forwarding.
42+
*/
43+
autoForwardAction: PortAutoForwardAction;
44+
45+
/**
46+
* Creates a new PortAttributes object
47+
* @param port the port number
48+
* @param autoForwardAction the action to take when this port is detected
49+
*/
50+
constructor(autoForwardAction: PortAutoForwardAction);
51+
}
52+
53+
/**
54+
* A provider of port attributes. Port attributes are used to determine what action should be taken when a port is discovered.
55+
*/
56+
export interface PortAttributesProvider {
57+
/**
58+
* Provides attributes for the given port. For ports that your extension doesn't know about, simply
59+
* return undefined. For example, if `providePortAttributes` is called with ports 3000 but your
60+
* extension doesn't know anything about 3000 you should return undefined.
61+
* @param port The port number of the port that attributes are being requested for.
62+
* @param pid The pid of the process that is listening on the port. If the pid is unknown, undefined will be passed.
63+
* @param commandLine The command line of the process that is listening on the port. If the command line is unknown, undefined will be passed.
64+
* @param token A cancellation token that indicates the result is no longer needed.
65+
*/
66+
providePortAttributes(attributes: { port: number; pid?: number; commandLine?: string }, token: CancellationToken): ProviderResult<PortAttributes>;
67+
}
68+
69+
/**
70+
* A selector that will be used to filter which {@link PortAttributesProvider} should be called for each port.
71+
*/
72+
export interface PortAttributesSelector {
73+
/**
74+
* Specifying a port range will cause your provider to only be called for ports within the range.
75+
* The start is inclusive and the end is exclusive.
76+
*/
77+
portRange?: [number, number] | number;
78+
79+
/**
80+
* Specifying a command pattern will cause your provider to only be called for processes whose command line matches the pattern.
81+
*/
82+
commandPattern?: RegExp;
83+
}
84+
85+
export namespace workspace {
86+
/**
87+
* If your extension listens on ports, consider registering a PortAttributesProvider to provide information
88+
* about the ports. For example, a debug extension may know about debug ports in it's debuggee. By providing
89+
* this information with a PortAttributesProvider the extension can tell the editor that these ports should be
90+
* ignored, since they don't need to be user facing.
91+
*
92+
* The results of the PortAttributesProvider are merged with the user setting `remote.portsAttributes`. If the values conflict, the user setting takes precedence.
93+
*
94+
* @param portSelector It is best practice to specify a port selector to avoid unnecessary calls to your provider.
95+
* If you don't specify a port selector your provider will be called for every port, which will result in slower port forwarding for the user.
96+
* @param provider The {@link PortAttributesProvider PortAttributesProvider}.
97+
*/
98+
export function registerPortAttributesProvider(portSelector: PortAttributesSelector, provider: PortAttributesProvider): Disposable;
99+
}
100+
}

0 commit comments

Comments
 (0)