mirror of
https://github.com/microsoft/vscode.git
synced 2026-08-28 23:19:46 +01:00
Merge pull request #193420 from microsoft/merogge/comment-help
add comment widget help dialog
This commit is contained in:
@@ -12,12 +12,14 @@ import { IAccessibleViewService, AccessibleViewService } from 'vs/workbench/cont
|
||||
import { UnfocusedViewDimmingContribution } from 'vs/workbench/contrib/accessibility/browser/unfocusedViewDimmingContribution';
|
||||
import { EditorAccessibilityHelpContribution, HoverAccessibleViewContribution, InlineCompletionsAccessibleViewContribution, NotificationAccessibleViewContribution } from 'vs/workbench/contrib/accessibility/browser/accessibilityContributions';
|
||||
import { AccessibilityStatus } from 'vs/workbench/contrib/accessibility/browser/accessibilityStatus';
|
||||
import { CommentsAccessibilityHelpContribution } from 'vs/workbench/contrib/comments/browser/comments.contribution';
|
||||
|
||||
registerAccessibilityConfiguration();
|
||||
registerSingleton(IAccessibleViewService, AccessibleViewService, InstantiationType.Delayed);
|
||||
|
||||
const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
|
||||
workbenchRegistry.registerWorkbenchContribution(EditorAccessibilityHelpContribution, LifecyclePhase.Eventually);
|
||||
workbenchRegistry.registerWorkbenchContribution(CommentsAccessibilityHelpContribution, LifecyclePhase.Eventually);
|
||||
workbenchRegistry.registerWorkbenchContribution(UnfocusedViewDimmingContribution, LifecyclePhase.Restored);
|
||||
|
||||
const workbenchContributionsRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
|
||||
|
||||
@@ -43,7 +43,8 @@ export const enum AccessibilityVerbositySettingId {
|
||||
Editor = 'accessibility.verbosity.editor',
|
||||
Hover = 'accessibility.verbosity.hover',
|
||||
Notification = 'accessibility.verbosity.notification',
|
||||
EmptyEditorHint = 'accessibility.verbosity.emptyEditorHint'
|
||||
EmptyEditorHint = 'accessibility.verbosity.emptyEditorHint',
|
||||
Comments = 'accessibility.verbosity.comments'
|
||||
}
|
||||
|
||||
export const enum AccessibleViewProviderId {
|
||||
@@ -57,7 +58,8 @@ export const enum AccessibleViewProviderId {
|
||||
Editor = 'editor',
|
||||
Hover = 'hover',
|
||||
Notification = 'notification',
|
||||
EmptyEditorHint = 'emptyEditorHint'
|
||||
EmptyEditorHint = 'emptyEditorHint',
|
||||
Comments = 'comments'
|
||||
}
|
||||
|
||||
const baseProperty: object = {
|
||||
@@ -110,6 +112,10 @@ const configuration: IConfigurationNode = {
|
||||
[AccessibilityVerbositySettingId.EmptyEditorHint]: {
|
||||
description: localize('verbosity.emptyEditorHint', 'Provide information about relevant actions in an empty text editor.'),
|
||||
...baseProperty
|
||||
},
|
||||
[AccessibilityVerbositySettingId.Comments]: {
|
||||
description: localize('verbosity.comments', 'Provide information about actions that can be taken in the comment widget or in a file which contains comments.'),
|
||||
...baseProperty
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -37,7 +37,10 @@ import { ThemeIcon } from 'vs/base/common/themables';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { InlineCompletionsController } from 'vs/editor/contrib/inlineCompletions/browser/inlineCompletionsController';
|
||||
import { InlineCompletionContextKeys } from 'vs/editor/contrib/inlineCompletions/browser/inlineCompletionContextKeys';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { CommentContextKeys } from 'vs/workbench/contrib/comments/common/commentContextKeys';
|
||||
import { CommentAccessibilityHelpNLS } from 'vs/workbench/contrib/comments/browser/comments.contribution';
|
||||
import { CommentCommandId } from 'vs/workbench/contrib/comments/common/commentCommandIds';
|
||||
|
||||
export class EditorAccessibilityHelpContribution extends Disposable {
|
||||
static ID: 'editorAccessibilityHelpContribution';
|
||||
@@ -66,7 +69,8 @@ class AccessibilityHelpProvider implements IAccessibleContentProvider {
|
||||
verbositySettingKey = AccessibilityVerbositySettingId.Editor;
|
||||
constructor(
|
||||
private readonly _editor: ICodeEditor,
|
||||
@IKeybindingService private readonly _keybindingService: IKeybindingService
|
||||
@IKeybindingService private readonly _keybindingService: IKeybindingService,
|
||||
@IContextKeyService private readonly _contextKeyService: IContextKeyService
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -96,6 +100,15 @@ class AccessibilityHelpProvider implements IAccessibleContentProvider {
|
||||
}
|
||||
}
|
||||
|
||||
const editorContext = this._contextKeyService.getContext(this._editor.getDomNode()!);
|
||||
if (editorContext.getValue<boolean>(CommentContextKeys.activeEditorHasCommentingRange.key)) {
|
||||
content.push(this._descriptionForCommand(CommentCommandId.Add, CommentAccessibilityHelpNLS.addComment, CommentAccessibilityHelpNLS.addCommentNoKb));
|
||||
content.push(this._descriptionForCommand(CommentCommandId.NextThread, CommentAccessibilityHelpNLS.nextCommentThreadKb, CommentAccessibilityHelpNLS.nextCommentThreadNoKb));
|
||||
content.push(this._descriptionForCommand(CommentCommandId.PreviousThread, CommentAccessibilityHelpNLS.previousCommentThreadKb, CommentAccessibilityHelpNLS.previousCommentThreadNoKb));
|
||||
content.push(this._descriptionForCommand(CommentCommandId.NextRange, CommentAccessibilityHelpNLS.nextRange, CommentAccessibilityHelpNLS.nextRangeNoKb));
|
||||
content.push(this._descriptionForCommand(CommentCommandId.PreviousRange, CommentAccessibilityHelpNLS.previousRange, CommentAccessibilityHelpNLS.previousRangeNoKb));
|
||||
}
|
||||
|
||||
if (options.get(EditorOption.stickyScroll).enabled) {
|
||||
content.push(this._descriptionForCommand('editor.action.focusStickyScroll', AccessibilityHelpNLS.stickScrollKb, AccessibilityHelpNLS.stickScrollNoKb));
|
||||
}
|
||||
|
||||
@@ -31,6 +31,10 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
|
||||
import { registerNavigableContainer } from 'vs/workbench/browser/actions/widgetNavigationCommands';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { COMMENTS_SECTION, ICommentsConfiguration } from 'vs/workbench/contrib/comments/common/commentsConfiguration';
|
||||
import { localize } from 'vs/nls';
|
||||
import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands';
|
||||
|
||||
export const COMMENTEDITOR_DECORATION_KEY = 'commenteditordecoration';
|
||||
|
||||
@@ -45,6 +49,7 @@ export class CommentThreadWidget<T extends IRange | ICellRange = IRange> extends
|
||||
private _threadIsEmpty: IContextKey<boolean>;
|
||||
private _styleElement: HTMLStyleElement;
|
||||
private _commentThreadContextValue: IContextKey<string | undefined>;
|
||||
private _focusedContextKey: IContextKey<boolean>;
|
||||
private _onDidResize = new Emitter<dom.Dimension>();
|
||||
onDidResize = this._onDidResize.event;
|
||||
|
||||
@@ -53,7 +58,6 @@ export class CommentThreadWidget<T extends IRange | ICellRange = IRange> extends
|
||||
get commentThread() {
|
||||
return this._commentThread;
|
||||
}
|
||||
|
||||
constructor(
|
||||
readonly container: HTMLElement,
|
||||
private _owner: string,
|
||||
@@ -71,12 +75,14 @@ export class CommentThreadWidget<T extends IRange | ICellRange = IRange> extends
|
||||
},
|
||||
@ICommentService private commentService: ICommentService,
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IConfigurationService private configurationService: IConfigurationService
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@IKeybindingService private _keybindingService: IKeybindingService
|
||||
) {
|
||||
super();
|
||||
|
||||
this._threadIsEmpty = CommentContextKeys.commentThreadIsEmpty.bindTo(this._contextKeyService);
|
||||
this._threadIsEmpty.set(!_commentThread.comments || !_commentThread.comments.length);
|
||||
this._focusedContextKey = CommentContextKeys.commentFocused.bindTo(this._contextKeyService);
|
||||
|
||||
this._commentMenus = this.commentService.getCommentMenus(this._owner);
|
||||
|
||||
@@ -111,7 +117,13 @@ export class CommentThreadWidget<T extends IRange | ICellRange = IRange> extends
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
this._register(tracker.onDidFocus(() => this._focusedContextKey.set(true)));
|
||||
this._register(tracker.onDidBlur(() => this._focusedContextKey.reset()));
|
||||
this._register(this.configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration(AccessibilityVerbositySettingId.Comments)) {
|
||||
this._setAriaLabel();
|
||||
}
|
||||
}));
|
||||
this._body = this._scopedInstantiationService.createInstance(
|
||||
CommentThreadBody,
|
||||
this._owner,
|
||||
@@ -124,7 +136,7 @@ export class CommentThreadWidget<T extends IRange | ICellRange = IRange> extends
|
||||
this
|
||||
) as unknown as CommentThreadBody<T>;
|
||||
this._register(this._body);
|
||||
|
||||
this._setAriaLabel();
|
||||
this._styleElement = dom.createStyleSheet(this.container);
|
||||
|
||||
|
||||
@@ -141,6 +153,21 @@ export class CommentThreadWidget<T extends IRange | ICellRange = IRange> extends
|
||||
this.currentThreadListeners();
|
||||
}
|
||||
|
||||
private _setAriaLabel(): void {
|
||||
let ariaLabel = localize('commentLabel', "Comment");
|
||||
let keybinding: string | undefined;
|
||||
const verbose = this.configurationService.getValue(AccessibilityVerbositySettingId.Comments);
|
||||
if (verbose) {
|
||||
keybinding = this._keybindingService.lookupKeybinding(AccessibilityCommandId.OpenAccessibilityHelp, this._contextKeyService)?.getLabel() ?? undefined;
|
||||
}
|
||||
if (keybinding) {
|
||||
ariaLabel = localize('commentLabelWithKeybinding', "{0}, use ({1}) for accessibility help", ariaLabel, keybinding);
|
||||
} else {
|
||||
ariaLabel = localize('commentLabelWithKeybindingNoKeybinding', "{0}, run the command Open Accessibility Help which is currently not triggerable via keybinding.", ariaLabel);
|
||||
}
|
||||
this._body.container.ariaLabel = ariaLabel;
|
||||
}
|
||||
|
||||
private updateCurrentThread(hasMouse: boolean, hasFocus: boolean) {
|
||||
if (hasMouse || hasFocus) {
|
||||
this.commentService.setCurrentCommentThread(this.commentThread);
|
||||
|
||||
@@ -9,6 +9,17 @@ import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import 'vs/workbench/contrib/comments/browser/commentsEditorContribution';
|
||||
import { ICommentService, CommentService } from 'vs/workbench/contrib/comments/browser/commentService';
|
||||
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { ctxCommentEditorFocused } from 'vs/workbench/contrib/comments/browser/simpleCommentEditor';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
|
||||
import { AccessibleViewType, IAccessibleContentProvider, IAccessibleViewOptions, IAccessibleViewService } from 'vs/workbench/contrib/accessibility/browser/accessibleView';
|
||||
import { AccessibilityHelpAction } from 'vs/workbench/contrib/accessibility/browser/accessibleViewActions';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { CommentContextKeys } from 'vs/workbench/contrib/comments/common/commentContextKeys';
|
||||
import { CommentCommandId } from 'vs/workbench/contrib/comments/common/commentCommandIds';
|
||||
|
||||
Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).registerConfiguration({
|
||||
id: 'comments',
|
||||
@@ -54,3 +65,63 @@ Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration).regis
|
||||
});
|
||||
|
||||
registerSingleton(ICommentService, CommentService, InstantiationType.Delayed);
|
||||
|
||||
|
||||
export namespace CommentAccessibilityHelpNLS {
|
||||
export const escape = nls.localize('escape', "Dismiss the comment widget via Escape.");
|
||||
export const nextRange = nls.localize('next', "Navigate to the next commenting range via ({0}).");
|
||||
export const nextRangeNoKb = nls.localize('nextNoKb', "Run the command: Go to Next Commenting Range, which is currently not triggerable via keybinding.");
|
||||
export const previousRange = nls.localize('previous', "Navigate to the previous comment range via ({0}).");
|
||||
export const previousRangeNoKb = nls.localize('previousNoKb', "Run the command: Go to Previous Commenting Range, which is currently not triggerable via keybinding.");
|
||||
export const nextCommentThreadKb = nls.localize('nextCommentThreadKb', "Navigate to the next comment thread via ({0}).");
|
||||
export const nextCommentThreadNoKb = nls.localize('nextCommentThreadNoKb', "Run the command: Go to Next Comment Thread, which is currently not triggerable via keybinding.");
|
||||
export const previousCommentThreadKb = nls.localize('previousCommentThreadKb', "Navigate to the previous comment thread via ({0}).");
|
||||
export const previousCommentThreadNoKb = nls.localize('previousCommentThreadNoKb', "Run the command: Go to Previous Comment Thread, which is currently not triggerable via keybinding.");
|
||||
export const addComment = nls.localize('addComment', "Add a comment via ({0}).");
|
||||
export const addCommentNoKb = nls.localize('addCommentNoKb', "Add a comment via the command: Add Comment on Current Selection, which is currently not triggerable via keybinding.");
|
||||
export const submitComment = nls.localize('submitComment', "Submit the comment via ({0}).");
|
||||
export const submitCommentNoKb = nls.localize('submitCommentNoKb', "Submit the comment by navigating with tab to the button, as it's currently not triggerable via keybinding.");
|
||||
}
|
||||
|
||||
export class CommentsAccessibilityHelpContribution extends Disposable {
|
||||
static ID: 'commentsAccessibilityHelpContribution';
|
||||
constructor() {
|
||||
super();
|
||||
this._register(AccessibilityHelpAction.addImplementation(110, 'comments', accessor => {
|
||||
const instantiationService = accessor.get(IInstantiationService);
|
||||
const accessibleViewService = accessor.get(IAccessibleViewService);
|
||||
accessibleViewService.show(instantiationService.createInstance(CommentsAccessibilityHelpProvider));
|
||||
return true;
|
||||
}, ContextKeyExpr.or(ctxCommentEditorFocused, CommentContextKeys.commentFocused)));
|
||||
}
|
||||
}
|
||||
export class CommentsAccessibilityHelpProvider implements IAccessibleContentProvider {
|
||||
verbositySettingKey: AccessibilityVerbositySettingId = AccessibilityVerbositySettingId.Comments;
|
||||
options: IAccessibleViewOptions = { type: AccessibleViewType.Help };
|
||||
private _element: HTMLElement | undefined;
|
||||
constructor(
|
||||
@IKeybindingService private readonly _keybindingService: IKeybindingService
|
||||
) {
|
||||
|
||||
}
|
||||
private _descriptionForCommand(commandId: string, msg: string, noKbMsg: string): string {
|
||||
const kb = this._keybindingService.lookupKeybinding(commandId);
|
||||
if (kb) {
|
||||
return strings.format(msg, kb.getAriaLabel());
|
||||
}
|
||||
return strings.format(noKbMsg, commandId);
|
||||
}
|
||||
provideContent(): string {
|
||||
this._element = document.activeElement as HTMLElement;
|
||||
const content: string[] = [];
|
||||
content.push(CommentAccessibilityHelpNLS.escape);
|
||||
content.push(this._descriptionForCommand(CommentCommandId.Add, CommentAccessibilityHelpNLS.addComment, CommentAccessibilityHelpNLS.addCommentNoKb));
|
||||
content.push(this._descriptionForCommand(CommentCommandId.NextRange, CommentAccessibilityHelpNLS.nextRange, CommentAccessibilityHelpNLS.nextRangeNoKb));
|
||||
content.push(this._descriptionForCommand(CommentCommandId.PreviousRange, CommentAccessibilityHelpNLS.previousRange, CommentAccessibilityHelpNLS.previousRangeNoKb));
|
||||
content.push(this._descriptionForCommand(CommentCommandId.Submit, CommentAccessibilityHelpNLS.submitComment, CommentAccessibilityHelpNLS.submitCommentNoKb));
|
||||
return content.join('\n\n');
|
||||
}
|
||||
onClose(): void {
|
||||
this._element?.focus();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,6 +40,9 @@ import { ICursorSelectionChangedEvent } from 'vs/editor/common/cursorEvents';
|
||||
import { CommentsPanel } from 'vs/workbench/contrib/comments/browser/commentsView';
|
||||
import { status } from 'vs/base/browser/ui/aria/aria';
|
||||
import { CommentContextKeys } from 'vs/workbench/contrib/comments/common/commentContextKeys';
|
||||
import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
|
||||
import { AccessibilityCommandId } from 'vs/workbench/contrib/accessibility/common/accessibilityCommands';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
|
||||
export const ID = 'editor.contrib.review';
|
||||
|
||||
@@ -380,7 +383,8 @@ export class CommentController implements IEditorContribution {
|
||||
@IViewsService private readonly viewsService: IViewsService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IEditorService private readonly editorService: IEditorService
|
||||
@IEditorService private readonly editorService: IEditorService,
|
||||
@IKeybindingService private readonly keybindingService: IKeybindingService
|
||||
) {
|
||||
this._commentInfos = [];
|
||||
this._commentWidgets = [];
|
||||
@@ -848,7 +852,17 @@ export class CommentController implements IEditorContribution {
|
||||
if (this._commentInfos.some(commentInfo => commentInfo.commentingRanges.ranges.length > 0 || commentInfo.commentingRanges.fileComments)) {
|
||||
this._hasRespondedToEditorChange = true;
|
||||
this._activeEditorHasCommentingRange.set(true);
|
||||
status(nls.localize('hasCommentRanges', "Editor has commenting ranges."));
|
||||
const verbose = this.configurationService.getValue(AccessibilityVerbositySettingId.Comments);
|
||||
if (verbose) {
|
||||
const keybinding = this.keybindingService.lookupKeybinding(AccessibilityCommandId.OpenAccessibilityHelp)?.getAriaLabel();
|
||||
if (keybinding) {
|
||||
status(nls.localize('hasCommentRangesKb', "Editor has commenting ranges, run the command Open Accessibility Help ({0}), for more information.", keybinding));
|
||||
} else {
|
||||
status(nls.localize('hasCommentRangesNoKb', "Editor has commenting ranges, run the command Open Accessibility Help, which is currently not triggerable via keybinding, for more information."));
|
||||
}
|
||||
} else {
|
||||
status(nls.localize('hasCommentRanges', "Editor has commenting ranges."));
|
||||
}
|
||||
} else {
|
||||
this._activeEditorHasCommentingRange.set(false);
|
||||
}
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import 'vs/css!./media/review';
|
||||
import { IActiveCodeEditor, ICodeEditor, isCodeEditor, isDiffEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { EditorAction, EditorContributionInstantiation, registerEditorAction, registerEditorContribution } from 'vs/editor/browser/editorExtensions';
|
||||
import { IActiveCodeEditor, isCodeEditor, isDiffEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { EditorContributionInstantiation, registerEditorContribution } from 'vs/editor/browser/editorExtensions';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import * as nls from 'vs/nls';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
@@ -21,101 +21,91 @@ import { CommentController, ID } from 'vs/workbench/contrib/comments/browser/com
|
||||
import { IRange, Range } from 'vs/editor/common/core/range';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { CommentContextKeys } from 'vs/workbench/contrib/comments/common/commentContextKeys';
|
||||
|
||||
export class NextCommentThreadAction extends EditorAction {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'editor.action.nextCommentThreadAction',
|
||||
label: nls.localize('nextCommentThreadAction', "Go to Next Comment Thread"),
|
||||
alias: 'Go to Next Comment Thread',
|
||||
precondition: undefined,
|
||||
kbOpts: {
|
||||
kbExpr: EditorContextKeys.focus,
|
||||
primary: KeyMod.Alt | KeyCode.F9,
|
||||
weight: KeybindingWeight.EditorContrib
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
|
||||
const controller = CommentController.get(editor);
|
||||
controller?.nextCommentThread();
|
||||
}
|
||||
}
|
||||
|
||||
export class PreviousCommentThreadAction extends EditorAction {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'editor.action.previousCommentThreadAction',
|
||||
label: nls.localize('previousCommentThreadAction', "Go to Previous Comment Thread"),
|
||||
alias: 'Go to Previous Comment Thread',
|
||||
precondition: undefined,
|
||||
kbOpts: {
|
||||
kbExpr: EditorContextKeys.focus,
|
||||
primary: KeyMod.Shift | KeyMod.Alt | KeyCode.F9,
|
||||
weight: KeybindingWeight.EditorContrib
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
|
||||
const controller = CommentController.get(editor);
|
||||
controller?.previousCommentThread();
|
||||
}
|
||||
}
|
||||
import { CONTEXT_ACCESSIBILITY_MODE_ENABLED } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { accessibilityHelpIsShown, accessibleViewCurrentProviderId, AccessibleViewProviderId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
|
||||
import { CommentCommandId } from 'vs/workbench/contrib/comments/common/commentCommandIds';
|
||||
|
||||
registerEditorContribution(ID, CommentController, EditorContributionInstantiation.AfterFirstRender);
|
||||
registerEditorAction(NextCommentThreadAction);
|
||||
registerEditorAction(PreviousCommentThreadAction);
|
||||
|
||||
export class NextCommentingRangeAction extends EditorAction {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'editor.action.goToNextCommentingRange',
|
||||
label: nls.localize('goToNextCommentingRange', "Go to Next Commenting Range"),
|
||||
alias: 'Go to Next Commenting Range',
|
||||
precondition: CommentContextKeys.WorkspaceHasCommenting,
|
||||
kbOpts: {
|
||||
kbExpr: EditorContextKeys.focus,
|
||||
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.DownArrow),
|
||||
weight: KeybindingWeight.EditorContrib
|
||||
}
|
||||
});
|
||||
}
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: CommentCommandId.NextThread,
|
||||
handler: async (accessor, args?: { range: IRange; fileComment: boolean }) => {
|
||||
const activeEditor = getActiveEditor(accessor);
|
||||
if (!activeEditor) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
|
||||
const controller = CommentController.get(editor);
|
||||
controller?.nextCommentingRange();
|
||||
}
|
||||
}
|
||||
const controller = CommentController.get(activeEditor);
|
||||
if (!controller) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
controller.nextCommentThread();
|
||||
},
|
||||
weight: KeybindingWeight.EditorContrib,
|
||||
when: EditorContextKeys.focus,
|
||||
primary: KeyMod.Alt | KeyCode.F9,
|
||||
});
|
||||
|
||||
export class PreviousCommentingRangeAction extends EditorAction {
|
||||
constructor() {
|
||||
super({
|
||||
id: 'editor.action.goToPreviousCommentingRange',
|
||||
label: nls.localize('goToPreviousCommentingRange', "Go to Previous Commenting Range"),
|
||||
alias: 'Go to Next Commenting Range',
|
||||
precondition: CommentContextKeys.WorkspaceHasCommenting,
|
||||
kbOpts: {
|
||||
kbExpr: EditorContextKeys.focus,
|
||||
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.UpArrow),
|
||||
weight: KeybindingWeight.EditorContrib
|
||||
}
|
||||
});
|
||||
}
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: CommentCommandId.PreviousThread,
|
||||
handler: async (accessor, args?: { range: IRange; fileComment: boolean }) => {
|
||||
const activeEditor = getActiveEditor(accessor);
|
||||
if (!activeEditor) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
|
||||
const controller = CommentController.get(editor);
|
||||
controller?.previousCommentingRange();
|
||||
}
|
||||
}
|
||||
const controller = CommentController.get(activeEditor);
|
||||
if (!controller) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
controller.previousCommentThread();
|
||||
},
|
||||
weight: KeybindingWeight.EditorContrib,
|
||||
when: EditorContextKeys.focus,
|
||||
primary: KeyMod.Shift | KeyMod.Alt | KeyCode.F9
|
||||
});
|
||||
|
||||
registerEditorAction(NextCommentingRangeAction);
|
||||
registerEditorAction(PreviousCommentingRangeAction);
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: CommentCommandId.NextRange,
|
||||
handler: async (accessor, args?: { range: IRange; fileComment: boolean }) => {
|
||||
const activeEditor = getActiveEditor(accessor);
|
||||
if (!activeEditor) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const controller = CommentController.get(activeEditor);
|
||||
if (!controller) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
controller.nextCommentingRange();
|
||||
},
|
||||
when: ContextKeyExpr.and(CONTEXT_ACCESSIBILITY_MODE_ENABLED, ContextKeyExpr.or(EditorContextKeys.focus, CommentContextKeys.commentFocused, ContextKeyExpr.and(accessibilityHelpIsShown, accessibleViewCurrentProviderId.isEqualTo(AccessibleViewProviderId.Comments)))),
|
||||
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.DownArrow),
|
||||
weight: KeybindingWeight.EditorContrib
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: CommentCommandId.PreviousRange,
|
||||
handler: async (accessor, args?: { range: IRange; fileComment: boolean }) => {
|
||||
const activeEditor = getActiveEditor(accessor);
|
||||
if (!activeEditor) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const controller = CommentController.get(activeEditor);
|
||||
if (!controller) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
controller.previousCommentingRange();
|
||||
},
|
||||
when: ContextKeyExpr.and(CONTEXT_ACCESSIBILITY_MODE_ENABLED, ContextKeyExpr.or(EditorContextKeys.focus, CommentContextKeys.commentFocused, ContextKeyExpr.and(accessibilityHelpIsShown, accessibleViewCurrentProviderId.isEqualTo(AccessibleViewProviderId.Comments)))),
|
||||
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KeyK, KeyMod.CtrlCmd | KeyMod.Alt | KeyCode.UpArrow),
|
||||
weight: KeybindingWeight.EditorContrib
|
||||
});
|
||||
|
||||
const TOGGLE_COMMENTING_COMMAND = 'workbench.action.toggleCommenting';
|
||||
CommandsRegistry.registerCommand({
|
||||
id: TOGGLE_COMMENTING_COMMAND,
|
||||
id: CommentCommandId.ToggleCommenting,
|
||||
handler: (accessor) => {
|
||||
const commentService = accessor.get(ICommentService);
|
||||
const enable = commentService.isCommentingEnabled;
|
||||
@@ -125,16 +115,15 @@ CommandsRegistry.registerCommand({
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: TOGGLE_COMMENTING_COMMAND,
|
||||
id: CommentCommandId.ToggleCommenting,
|
||||
title: nls.localize('comments.toggleCommenting', "Toggle Editor Commenting"),
|
||||
category: 'Comments',
|
||||
},
|
||||
when: CommentContextKeys.WorkspaceHasCommenting
|
||||
});
|
||||
|
||||
const ADD_COMMENT_COMMAND = 'workbench.action.addComment';
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: ADD_COMMENT_COMMAND,
|
||||
id: CommentCommandId.Add,
|
||||
handler: async (accessor, args?: { range: IRange; fileComment: boolean }) => {
|
||||
const activeEditor = getActiveEditor(accessor);
|
||||
if (!activeEditor) {
|
||||
@@ -161,16 +150,15 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: ADD_COMMENT_COMMAND,
|
||||
id: CommentCommandId.Add,
|
||||
title: nls.localize('comments.addCommand', "Add Comment on Current Selection"),
|
||||
category: 'Comments'
|
||||
},
|
||||
when: CommentContextKeys.activeCursorHasCommentingRange
|
||||
});
|
||||
|
||||
const COLLAPSE_ALL_COMMENT_COMMAND = 'workbench.action.collapseAllComments';
|
||||
CommandsRegistry.registerCommand({
|
||||
id: COLLAPSE_ALL_COMMENT_COMMAND,
|
||||
id: CommentCommandId.CollapseAll,
|
||||
handler: (accessor) => {
|
||||
return getActiveController(accessor)?.collapseAll();
|
||||
}
|
||||
@@ -178,16 +166,15 @@ CommandsRegistry.registerCommand({
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: COLLAPSE_ALL_COMMENT_COMMAND,
|
||||
id: CommentCommandId.CollapseAll,
|
||||
title: nls.localize('comments.collapseAll', "Collapse All Comments"),
|
||||
category: 'Comments'
|
||||
},
|
||||
when: CommentContextKeys.WorkspaceHasCommenting
|
||||
});
|
||||
|
||||
const EXPAND_ALL_COMMENT_COMMAND = 'workbench.action.expandAllComments';
|
||||
CommandsRegistry.registerCommand({
|
||||
id: EXPAND_ALL_COMMENT_COMMAND,
|
||||
id: CommentCommandId.ExpandAll,
|
||||
handler: (accessor) => {
|
||||
return getActiveController(accessor)?.expandAll();
|
||||
}
|
||||
@@ -195,16 +182,15 @@ CommandsRegistry.registerCommand({
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: EXPAND_ALL_COMMENT_COMMAND,
|
||||
id: CommentCommandId.ExpandAll,
|
||||
title: nls.localize('comments.expandAll', "Expand All Comments"),
|
||||
category: 'Comments'
|
||||
},
|
||||
when: CommentContextKeys.WorkspaceHasCommenting
|
||||
});
|
||||
|
||||
const EXPAND_UNRESOLVED_COMMENT_COMMAND = 'workbench.action.expandUnresolvedComments';
|
||||
CommandsRegistry.registerCommand({
|
||||
id: EXPAND_UNRESOLVED_COMMENT_COMMAND,
|
||||
id: CommentCommandId.ExpandUnresolved,
|
||||
handler: (accessor) => {
|
||||
return getActiveController(accessor)?.expandUnresolved();
|
||||
}
|
||||
@@ -212,7 +198,7 @@ CommandsRegistry.registerCommand({
|
||||
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: EXPAND_UNRESOLVED_COMMENT_COMMAND,
|
||||
id: CommentCommandId.ExpandUnresolved,
|
||||
title: nls.localize('comments.expandUnresolved', "Expand Unresolved Comments"),
|
||||
category: 'Comments'
|
||||
},
|
||||
@@ -220,7 +206,7 @@ MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'workbench.action.submitComment',
|
||||
id: CommentCommandId.Submit,
|
||||
weight: KeybindingWeight.EditorContrib,
|
||||
primary: KeyMod.CtrlCmd | KeyCode.Enter,
|
||||
when: ctxCommentEditorFocused,
|
||||
@@ -233,7 +219,7 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'workbench.action.hideComment',
|
||||
id: CommentCommandId.Hide,
|
||||
weight: KeybindingWeight.EditorContrib,
|
||||
primary: KeyCode.Escape,
|
||||
secondary: [KeyMod.Shift | KeyCode.Escape],
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export const enum CommentCommandId {
|
||||
Add = 'workbench.action.addComment',
|
||||
NextThread = 'editor.action.nextCommentThreadAction',
|
||||
PreviousThread = 'editor.action.previousCommentThreadAction',
|
||||
NextRange = 'editor.action.nextCommentingRange',
|
||||
PreviousRange = 'editor.action.previousCommentingRange',
|
||||
ToggleCommenting = 'workbench.action.toggleCommenting',
|
||||
Submit = 'editor.action.submitComment',
|
||||
Hide = 'workbench.action.hideComment',
|
||||
CollapseAll = 'workbench.action.collapseAllComments',
|
||||
ExpandAll = 'workbench.action.expandAllComments',
|
||||
ExpandUnresolved = 'workbench.action.expandUnresolvedComments'
|
||||
}
|
||||
@@ -53,4 +53,9 @@ export namespace CommentContextKeys {
|
||||
* The comment controller id associated with a comment thread.
|
||||
*/
|
||||
export const commentControllerContext = new RawContextKey<string>('commentController', undefined, { type: 'string', description: nls.localize('commentController', "The comment controller id associated with a comment thread") });
|
||||
|
||||
/**
|
||||
* The comment widget is focused.
|
||||
*/
|
||||
export const commentFocused = new RawContextKey<boolean>('commentFocused', false, { type: 'boolean', description: nls.localize('commentFocused', "Set when the comment is focused") });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user