Skip to content

Commit a2b4016

Browse files
committed
adding source highlighting class
1 parent 9aa36f2 commit a2b4016

2 files changed

Lines changed: 82 additions & 0 deletions

File tree

src/desktop/extension.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { GenericCommands } from '../features/generic-commands';
2727
import { ComponentViewer } from '../views/component-viewer/component-viewer';
2828
import { ComponentViewerTreeDataProvider } from '../views/component-viewer/component-viewer-tree-view';
2929
import { CorePeripherals } from '../views/core-peripherals/core-peripherals';
30+
import {SourceFileHighlighting} from '../features/source-file-highlighting/source-file-highlighting';
3031

3132
const BUILTIN_TOOLS_PATHS = [
3233
'tools/pyocd/pyocd',
@@ -58,6 +59,7 @@ export const activate = async (context: vscode.ExtensionContext): Promise<void>
5859
corePeripheralsTreeDataProvider = new ComponentViewerTreeDataProvider();
5960
const componentViewer = new ComponentViewer(context, componentViewerTreeDataProvider);
6061
const corePeripherals = new CorePeripherals(context, corePeripheralsTreeDataProvider);
62+
const sourceFileHighlighting = new SourceFileHighlighting(context);
6163

6264
addToolsToPath(context, BUILTIN_TOOLS_PATHS);
6365
// Activate generic commands
@@ -69,6 +71,7 @@ export const activate = async (context: vscode.ExtensionContext): Promise<void>
6971
cpuStates.activate(gdbtargetDebugTracker);
7072
cpuStatesCommands.activate(context, cpuStates);
7173
cpuStatesStatusBarItem.activate(context, cpuStates);
74+
sourceFileHighlighting.activate();
7275
// Live Watch view
7376
logger.debug('Activating Live Watch Tree Data Provider');
7477
if (!await liveWatchTreeDataProvider.activate(gdbtargetDebugTracker)) {
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/**
2+
* Copyright 2026 Arm Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import * as vscode from 'vscode';
18+
import { DebugProtocol } from '@vscode/debugprotocol';
19+
20+
export class SourceFileHighlighting {
21+
private activeDebugSession: vscode.DebugSession | undefined;
22+
private context: vscode.ExtensionContext;
23+
private executableLineDecorator = vscode.window.createTextEditorDecorationType({
24+
// turn it red for testing
25+
backgroundColor: 'rgba(255, 0, 0, 0.3)',
26+
// only highlight the margin of the line to avoid obscuring code
27+
isWholeLine: true,
28+
});
29+
30+
constructor(context: vscode.ExtensionContext) {
31+
this.context = context;
32+
}
33+
34+
public activate(): void {
35+
this.registerToTrackerEvents();
36+
vscode.window.onDidChangeActiveTextEditor(editor => {
37+
this.handleOnDidChangeActiveTextEditor(editor);
38+
});
39+
}
40+
41+
private registerToTrackerEvents(): void {
42+
const onDidChangeActiveDebugSessionDisposable = vscode.debug.onDidChangeActiveDebugSession(session => {
43+
this.activeDebugSession = session;
44+
});
45+
this.context.subscriptions.push(onDidChangeActiveDebugSessionDisposable);
46+
}
47+
48+
private async handleOnDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined): Promise<void> {
49+
if (!editor || !this.activeDebugSession) {
50+
return;
51+
}
52+
const breakpointLocations = await this.getBreakpointLocations(editor);
53+
if (!breakpointLocations) {
54+
return;
55+
}
56+
const executableLines = new Set(breakpointLocations.breakpoints.map((bp: DebugProtocol.BreakpointLocation) => bp.line));
57+
const decorations: vscode.DecorationOptions[] = Array.from(executableLines).map((exeline: number) => {
58+
const line = exeline - 1; // Convert to 0-based index
59+
return {
60+
range: new vscode.Range(line, 0, line, 0),
61+
};
62+
});
63+
editor.setDecorations(this.executableLineDecorator, decorations);
64+
}
65+
66+
private async getBreakpointLocations(editor: vscode.TextEditor): Promise<DebugProtocol.BreakpointLocationsResponse['body'] | void> {
67+
if(editor.document.uri.scheme !== 'file') {
68+
return;
69+
}
70+
const currentSourceFile = editor.document.fileName;
71+
const args : DebugProtocol.BreakpointLocationsArguments = {
72+
source: { path: currentSourceFile },
73+
line: 1,
74+
endLine: editor.document.lineCount, // Requesting breakpoint locations for the whole file
75+
};
76+
const breakpointLocations = await this.activeDebugSession?.customRequest('breakpointLocations', args);
77+
return breakpointLocations;
78+
}
79+
}

0 commit comments

Comments
 (0)