diff --git a/src/vs/base/browser/formattedTextRenderer.ts b/src/vs/base/browser/formattedTextRenderer.ts
index 14f7493fd463a..4af9e9ed4e9f6 100644
--- a/src/vs/base/browser/formattedTextRenderer.ts
+++ b/src/vs/base/browser/formattedTextRenderer.ts
@@ -91,6 +91,7 @@ function _renderFormattedText(element: Node, treeNode: IFormatParseTree, actionH
child = document.createElement('code');
} else if (treeNode.type === FormatType.Action && actionHandler) {
const a = document.createElement('a');
+ a.setAttribute('data-content-index', String(treeNode.index));
actionHandler.disposables.add(DOM.addStandardDisposableListener(a, 'click', (event) => {
actionHandler.callback(String(treeNode.index), event);
}));
diff --git a/src/vs/base/test/browser/formattedTextRenderer.test.ts b/src/vs/base/test/browser/formattedTextRenderer.test.ts
index 40147706cd51e..ae9108a37cebd 100644
--- a/src/vs/base/test/browser/formattedTextRenderer.test.ts
+++ b/src/vs/base/test/browser/formattedTextRenderer.test.ts
@@ -78,6 +78,7 @@ suite('FormattedTextRenderer', () => {
}
});
assert.strictEqual(result.innerHTML, 'action');
+ assert.strictEqual(result.firstChild!.getAttribute('data-content-index'), '0');
const event: MouseEvent = document.createEvent('MouseEvent');
event.initEvent('click', true, true);
@@ -97,6 +98,7 @@ suite('FormattedTextRenderer', () => {
}
});
assert.strictEqual(result.innerHTML, 'action');
+ assert.strictEqual(result.firstChild!.firstChild!.firstChild!.getAttribute('data-content-index'), '0');
const event: MouseEvent = document.createEvent('MouseEvent');
event.initEvent('click', true, true);
@@ -117,6 +119,7 @@ suite('FormattedTextRenderer', () => {
}
});
assert.strictEqual(result.innerHTML, 'action');
+ assert.strictEqual(result.firstChild!.firstChild!.firstChild!.firstChild!.getAttribute('data-content-index'), '0');
const event: MouseEvent = document.createEvent('MouseEvent');
event.initEvent('click', true, true);
diff --git a/src/vs/workbench/contrib/codeEditor/browser/emptyTextEditorHint/emptyTextEditorHint.ts b/src/vs/workbench/contrib/codeEditor/browser/emptyTextEditorHint/emptyTextEditorHint.ts
index 3d1899f8ec785..f1341320d59c7 100644
--- a/src/vs/workbench/contrib/codeEditor/browser/emptyTextEditorHint/emptyTextEditorHint.ts
+++ b/src/vs/workbench/contrib/codeEditor/browser/emptyTextEditorHint/emptyTextEditorHint.ts
@@ -6,6 +6,7 @@
import { $, addDisposableListener, getActiveWindow } from '../../../../../base/browser/dom.js';
import { IContentActionHandler, renderFormattedText } from '../../../../../base/browser/formattedTextRenderer.js';
import { StandardMouseEvent } from '../../../../../base/browser/mouseEvent.js';
+import { StandardKeyboardEvent } from '../../../../../base/browser/keyboardEvent.js';
import { status } from '../../../../../base/browser/ui/aria/aria.js';
import { WorkbenchActionExecutedClassification, WorkbenchActionExecutedEvent } from '../../../../../base/common/actions.js';
import { Event } from '../../../../../base/common/event.js';
@@ -271,6 +272,18 @@ class EmptyTextEditorHintContentWidget extends Disposable implements IContentWid
// eslint-disable-next-line no-restricted-syntax
for (const anchor of hintElement.querySelectorAll('a')) {
anchor.style.cursor = 'pointer';
+ anchor.tabIndex = 0;
+ anchor.setAttribute('role', 'button');
+ anchor.addEventListener('keydown', (e: KeyboardEvent) => {
+ if (e.key === 'Enter' || e.key === ' ') {
+ e.preventDefault();
+ e.stopPropagation();
+ const index = anchor.getAttribute('data-content-index');
+ if (index !== null) {
+ hintHandler.callback(index, new StandardKeyboardEvent(e));
+ }
+ }
+ });
}
return { hintElement, ariaLabel };