Skip to content

Commit 42a54e7

Browse files
Add inlie provider
1 parent 7acf3f3 commit 42a54e7

File tree

3 files changed

+90
-59
lines changed

3 files changed

+90
-59
lines changed

src/extension/common/vscodeapi.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,7 @@ export function startDebugging(
128128
) {
129129
debug.startDebugging(folder, nameOrConfiguration, parentSession);
130130
}
131+
132+
export function customRequest(command: string, args?: any): any {
133+
return debug.activeDebugSession?.customRequest(command, args);
134+
}

src/extension/debugger/inlineValue/pythonInlineValueProvider.ts

Lines changed: 82 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,93 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

4-
import { commands, debug, InlineValue, InlineValueContext, InlineValueEvaluatableExpression, InlineValuesProvider, InlineValueText, InlineValueVariableLookup,
5-
Range, TextDocument } from "vscode";
6-
import { executeCommand } from "../../common/vscodeapi";
7-
4+
import {
5+
debug,
6+
InlineValue,
7+
InlineValueContext,
8+
InlineValuesProvider,
9+
Range,
10+
TextDocument,
11+
InlineValueVariableLookup,
12+
} from 'vscode';
13+
import { customRequest } from '../../common/vscodeapi';
814

915
export class PythonInlineValueProvider implements InlineValuesProvider {
16+
public async provideInlineValues(
17+
document: TextDocument,
18+
viewPort: Range,
19+
context: InlineValueContext,
20+
): Promise<InlineValue[]> {
21+
let scopesRequest = await customRequest('scopes', { frameId: context.frameId });
22+
let variablesRequest = await customRequest('variables', {
23+
variablesReference: scopesRequest.scopes[0].variablesReference,
24+
});
1025

11-
public async provideInlineValues(document: TextDocument, viewPort: Range, context: InlineValueContext): Promise<InlineValue[]> {
12-
console.log("inline provider");
13-
let a = JSON.stringify(context);
14-
const allValues: InlineValue[] = [];
15-
16-
for (let l = 0; l <= context.stoppedLocation.end.line; l++) {
17-
const line = document.lineAt(l);
18-
var re = /\b[a-zA-Z_][a-zA-Z0-9_]*\b/g;
19-
do {
20-
var m = re.exec(line.text);
21-
if (m) {
22-
const varName = m[0];
23-
const rng = new Range(l, m.index, l, m.index + varName.length);
26+
//https://docs.python.org/3/reference/lexical_analysis.html#keywords
27+
const pythonKeywords = [
28+
'False',
29+
'await',
30+
'else',
31+
'import ',
32+
'pass',
33+
'None',
34+
'break',
35+
'except',
36+
'in',
37+
'raise',
38+
'True',
39+
'class',
40+
'finally',
41+
'is',
42+
'return',
43+
'and',
44+
'continue',
45+
'for',
46+
'lambda',
47+
'try',
48+
'as',
49+
'def',
50+
'from',
51+
'nonlocal',
52+
'while',
53+
'assert',
54+
'del',
55+
'global',
56+
'not',
57+
'with',
58+
'async',
59+
'elif',
60+
'if',
61+
'or',
62+
'yield',
63+
];
2464

25-
//allValues.push(new vscode.InlineValueText(r, `${varName}: some value`));
26-
allValues.push(new InlineValueVariableLookup(rng, varName));
27-
//allValues.push(new vscode.InlineValueEvaluatableExpression(r, varName));
28-
}
29-
} while (m);
30-
}
65+
const pythonVariables: any[] = variablesRequest.variables
66+
.filter((variable: any) => variable.type)
67+
.map((variable: any) => variable.name);
3168

32-
return allValues;
33-
// let variables = await resolveInlineVariables({
34-
// uri: document.uri.toString(),
35-
// viewPort: viewPort,
36-
// stoppedLocation: context.stoppedLocation,
37-
// });
69+
//VariableRegex for matching variables names in a python file, excluding strings
70+
let variableRegex = /(?<!['"\w])\b[a-zA-Z_][a-zA-Z0-9_]*\b(?![^"\n]*"(?:(?:[^"\n]*"){2})*[^"\n]*$)/g;
71+
const allValues: InlineValue[] = [];
72+
for (let l = viewPort.start.line; l <= viewPort.end.line; l++) {
73+
const line = document.lineAt(l);
74+
// Skip comments
75+
if (line.text.trimStart().startsWith('#')) {
76+
continue;
77+
}
3878

39-
return [];
79+
for (let match = variableRegex.exec(line.text); match; match = variableRegex.exec(line.text)) {
80+
let varName = match[0];
81+
// Skip python keywords
82+
if (pythonKeywords.includes(varName)) {
83+
continue;
84+
}
85+
if (pythonVariables.includes(varName)) {
86+
const rng = new Range(l, match.index, l, match.index + varName.length);
87+
allValues.push(new InlineValueVariableLookup(rng, varName, false));
88+
}
89+
}
90+
}
91+
return allValues;
4092
}
4193
}
42-
43-
// tslint:disable-next-line:interface-name
44-
export interface InlineParams {
45-
uri: string;
46-
viewPort?: Range;
47-
stoppedLocation: Range;
48-
}
49-
50-
// tslint:disable-next-line:interface-name
51-
export enum InlineKind {
52-
VariableLookup = 0,
53-
Evaluation = 1,
54-
}
55-
56-
// tslint:disable-next-line:interface-name
57-
export interface InlineVariable {
58-
range: Range;
59-
name: string;
60-
kind: InlineKind;
61-
expression: string;
62-
declaringClass: string;
63-
}
64-
65-
export async function resolveInlineVariables(inlineParams: InlineParams): Promise<InlineVariable[]> {
66-
debug.startDebugging;
67-
return <InlineVariable[]> await executeCommand("vscode.debug.resolveInlineVariables", JSON.stringify(inlineParams));
68-
}

src/extension/extensionInit.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export async function registerDebugger(context: IExtensionContext): Promise<IExt
137137
context.subscriptions.push(
138138
debug.registerDebugAdapterDescriptorFactory(DebuggerTypeName, debugAdapterDescriptorFactory),
139139
);
140-
140+
141141
context.subscriptions.push(
142142
debug.onDidStartDebugSession((debugSession) => {
143143
const shouldTerminalFocusOnStart = getConfiguration('python', debugSession.workspaceFolder?.uri)?.terminal
@@ -208,7 +208,9 @@ export async function registerDebugger(context: IExtensionContext): Promise<IExt
208208
}),
209209
);
210210

211-
context.subscriptions.push(languages.registerInlineValuesProvider({language: 'python'}, new PythonInlineValueProvider()));
211+
context.subscriptions.push(
212+
languages.registerInlineValuesProvider({ language: 'python' }, new PythonInlineValueProvider()),
213+
);
212214

213215
return buildApi();
214216
}

0 commit comments

Comments
 (0)