Skip to content

Commit 9210aed

Browse files
authored
Add source code highlighting (#224)
* Add source file highlighting support * Change highlighting colour to grey
1 parent 114155b commit 9210aed

2 files changed

Lines changed: 117 additions & 0 deletions

File tree

src/SourceFileHighlighting.ts

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*********************************************************************
2+
* Copyright (c) 2026 Arm Limited and others
3+
*
4+
* This program and the accompanying materials are made
5+
* available under the terms of the Eclipse Public License 2.0
6+
* which is available at https://www.eclipse.org/legal/epl-2.0/
7+
*
8+
* SPDX-License-Identifier: EPL-2.0
9+
*********************************************************************/
10+
11+
import * as vscode from 'vscode';
12+
import { DebugProtocol } from '@vscode/debugprotocol';
13+
14+
export class SourceFileHighlighting {
15+
private activeDebugSession: vscode.DebugSession | undefined;
16+
private context: vscode.ExtensionContext;
17+
private executableLineDecorator =
18+
vscode.window.createTextEditorDecorationType({
19+
borderWidth: '0 0 0 2px',
20+
borderStyle: 'solid',
21+
borderColor: new vscode.ThemeColor('editorLineNumber.foreground'),
22+
isWholeLine: true,
23+
});
24+
25+
constructor(context: vscode.ExtensionContext) {
26+
this.context = context;
27+
}
28+
29+
public activate(): void {
30+
this.registerToEvents();
31+
}
32+
33+
private registerToEvents(): void {
34+
const onDidChangeActiveDebugSessionDisposable =
35+
vscode.debug.onDidChangeActiveDebugSession((session) => {
36+
if (!session) {
37+
this.clearExecutableLineDecorations(
38+
vscode.window.visibleTextEditors
39+
);
40+
}
41+
this.activeDebugSession = session;
42+
this.handleOnDidChangeActiveTextEditor(
43+
vscode.window.activeTextEditor
44+
);
45+
});
46+
const onDidChangeActiveTextEditorDisposable =
47+
vscode.window.onDidChangeActiveTextEditor((editor) => {
48+
this.handleOnDidChangeActiveTextEditor(editor);
49+
});
50+
51+
this.context.subscriptions.push(
52+
onDidChangeActiveDebugSessionDisposable,
53+
onDidChangeActiveTextEditorDisposable
54+
);
55+
}
56+
57+
private clearExecutableLineDecorations(
58+
editors: readonly vscode.TextEditor[]
59+
): void {
60+
for (const editor of editors) {
61+
editor.setDecorations(this.executableLineDecorator, []);
62+
}
63+
}
64+
65+
private async handleOnDidChangeActiveTextEditor(
66+
editor: vscode.TextEditor | undefined
67+
): Promise<void> {
68+
if (!editor) {
69+
return;
70+
}
71+
if (!this.activeDebugSession) {
72+
this.clearExecutableLineDecorations([editor]);
73+
return;
74+
}
75+
const breakpointLocations = await this.getBreakpointLocations(editor);
76+
if (!breakpointLocations) {
77+
this.clearExecutableLineDecorations([editor]);
78+
return;
79+
}
80+
const executableLines = new Set(
81+
breakpointLocations.breakpoints.map(
82+
(bp: DebugProtocol.BreakpointLocation) => bp.line
83+
)
84+
);
85+
const decorations: vscode.DecorationOptions[] = Array.from(
86+
executableLines
87+
).map((exeline: number) => {
88+
const line = exeline - 1; // Convert to 0-based index
89+
return {
90+
range: new vscode.Range(line, 0, line, 0),
91+
};
92+
});
93+
editor.setDecorations(this.executableLineDecorator, decorations);
94+
}
95+
96+
private async getBreakpointLocations(
97+
editor: vscode.TextEditor
98+
): Promise<DebugProtocol.BreakpointLocationsResponse['body'] | void> {
99+
if (editor.document.uri.scheme !== 'file') {
100+
return;
101+
}
102+
const currentSourceFile = editor.document.fileName;
103+
const args: DebugProtocol.BreakpointLocationsArguments = {
104+
source: { path: currentSourceFile },
105+
line: 1,
106+
endLine: editor.document.lineCount, // Requesting breakpoint locations for the whole file
107+
};
108+
const breakpointLocations =
109+
await this.activeDebugSession?.customRequest(
110+
'breakpointLocations',
111+
args
112+
);
113+
return breakpointLocations;
114+
}
115+
}

src/extension.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,15 @@ export { CustomReset } from './CustomReset';
1919
import { SwitchRadix } from './switchRadix';
2020
export { SwitchRadix } from './switchRadix';
2121
import { BreakpointModesController } from './BreakpointModesController';
22+
import { SourceFileHighlighting } from './SourceFileHighlighting';
2223

2324
export function activate(context: ExtensionContext) {
2425
new MemoryServer(context);
2526
new ResumeAllSession(context);
2627
new SuspendAllSession(context);
2728
new CustomReset(context);
2829
new SwitchRadix(context);
30+
new SourceFileHighlighting(context).activate();
2931
context.subscriptions.push(
3032
commands.registerCommand('cdt.debug.askProgramPath', (_config) => {
3133
return window.showInputBox({

0 commit comments

Comments
 (0)