Expose comment editor to extension API and add new menu (#169831)

* Expose comment editor to extension API and add new menu
Fixes #169737

* Also add in comment node
This commit is contained in:
Alex Ross
2022-12-22 14:36:40 +01:00
committed by GitHub
parent 77fc799cf3
commit baf257dafb
8 changed files with 86 additions and 7 deletions
@@ -126,6 +126,7 @@ export class MenuId {
static readonly ViewContainerTitleContext = new MenuId('ViewContainerTitleContext');
static readonly ViewTitle = new MenuId('ViewTitle');
static readonly ViewTitleContext = new MenuId('ViewTitleContext');
static readonly CommentEditorActions = new MenuId('CommentEditorActions');
static readonly CommentThreadTitle = new MenuId('CommentThreadTitle');
static readonly CommentThreadActions = new MenuId('CommentThreadActions');
static readonly CommentThreadAdditionalActions = new MenuId('CommentThreadAdditionalActions');
@@ -23,6 +23,10 @@ export class CommentMenus implements IDisposable {
return this.getMenu(MenuId.CommentThreadActions, contextKeyService);
}
getCommentEditorActions(contextKeyService: IContextKeyService): IMenu {
return this.getMenu(MenuId.CommentEditorActions, contextKeyService);
}
getCommentThreadAdditionalActions(contextKeyService: IContextKeyService): IMenu {
return this.getMenu(MenuId.CommentThreadAdditionalActions, contextKeyService);
}
@@ -67,6 +67,7 @@ export class CommentNode<T extends IRange | ICellRange> extends Disposable {
protected actionRunner?: IActionRunner;
protected toolbar: ToolBar | undefined;
private _commentFormActions: CommentFormActions | null = null;
private _commentEditorActions: CommentFormActions | null = null;
private readonly _onDidClick = new Emitter<CommentNode<T>>();
@@ -469,8 +470,16 @@ export class CommentNode<T extends IRange | ICellRange> extends Disposable {
this._body.classList.add('hidden');
this._commentEditContainer = dom.append(this._commentDetailsContainer, dom.$('.edit-container'));
this.createCommentEditor(this._commentEditContainer);
const formActions = dom.append(this._commentEditContainer, dom.$('.form-actions'));
const formActions = dom.append(this._commentEditContainer, dom.$('.form-actions'));
const otherActions = dom.append(formActions, dom.$('.other-actions'));
this.createCommentWidgetFormActions(otherActions);
const editorActions = dom.append(formActions, dom.$('.editor-actions'));
this.createCommentWidgetEditorActions(editorActions);
}
private createCommentWidgetFormActions(container: HTMLElement) {
const menus = this.commentService.getCommentMenus(this.owner);
const menu = menus.getCommentActions(this.comment, this._contextKeyService);
@@ -479,7 +488,7 @@ export class CommentNode<T extends IRange | ICellRange> extends Disposable {
this._commentFormActions?.setActions(menu);
}));
this._commentFormActions = new CommentFormActions(formActions, (action: IAction): void => {
this._commentFormActions = new CommentFormActions(container, (action: IAction): void => {
const text = this._commentEditor!.getValue();
action.run({
@@ -496,6 +505,32 @@ export class CommentNode<T extends IRange | ICellRange> extends Disposable {
this._commentFormActions.setActions(menu);
}
private createCommentWidgetEditorActions(container: HTMLElement) {
const menus = this.commentService.getCommentMenus(this.owner);
const menu = menus.getCommentEditorActions(this._contextKeyService);
this._register(menu);
this._register(menu.onDidChange(() => {
this._commentEditorActions?.setActions(menu);
}));
this._commentEditorActions = new CommentFormActions(container, (action: IAction): void => {
const text = this._commentEditor!.getValue();
action.run({
thread: this.commentThread,
commentUniqueId: this.comment.uniqueIdInThread,
text: text,
$mid: MarshalledId.CommentThreadNode
});
this._commentEditor?.focus();
});
this._register(this._commentEditorActions);
this._commentEditorActions.setActions(menu, true);
}
setFocus(focused: boolean, visible: boolean = false) {
if (focused) {
this._domNode.focus();
@@ -40,8 +40,10 @@ export class CommentReply<T extends IRange | ICellRange> extends Disposable {
commentEditorIsEmpty: IContextKey<boolean>;
private _error!: HTMLElement;
private _formActions: HTMLElement | null;
private _editorActions: HTMLElement | null;
private _commentThreadDisposables: IDisposable[] = [];
private _commentFormActions!: CommentFormActions;
private _commentEditorActions!: CommentFormActions;
private _reviewThreadReplyButton!: HTMLElement;
constructor(
@@ -103,9 +105,11 @@ export class CommentReply<T extends IRange | ICellRange> extends Disposable {
}
}
this._error = dom.append(this.form, dom.$('.validation-error.hidden'));
this._formActions = dom.append(this.form, dom.$('.form-actions'));
this.createCommentWidgetActions(this._formActions, model);
const formActions = dom.append(this.form, dom.$('.form-actions'));
this._formActions = dom.append(formActions, dom.$('.other-actions'));
this.createCommentWidgetFormActions(this._formActions, model);
this._editorActions = dom.append(formActions, dom.$('.editor-actions'));
this.createCommentWidgetEditorActions(this._editorActions, model);
}
public updateCommentThread(commentThread: languages.CommentThread<IRange | ICellRange>) {
@@ -241,7 +245,7 @@ export class CommentReply<T extends IRange | ICellRange> extends Disposable {
/**
* Command based actions.
*/
private createCommentWidgetActions(container: HTMLElement, model: ITextModel) {
private createCommentWidgetFormActions(container: HTMLElement, model: ITextModel) {
const menu = this._commentMenus.getCommentThreadActions(this._contextKeyService);
this._register(menu);
@@ -265,6 +269,29 @@ export class CommentReply<T extends IRange | ICellRange> extends Disposable {
this._commentFormActions.setActions(menu);
}
private createCommentWidgetEditorActions(container: HTMLElement, model: ITextModel) {
const editorMenu = this._commentMenus.getCommentEditorActions(this._contextKeyService);
this._register(editorMenu);
this._register(editorMenu.onDidChange(() => {
this._commentEditorActions.setActions(editorMenu);
}));
this._commentEditorActions = new CommentFormActions(container, async (action: IAction) => {
this._actionRunDelegate?.();
action.run({
thread: this._commentThread,
text: this.commentEditor.getValue(),
$mid: MarshalledId.CommentThreadReply
});
this.focusCommentEditor();
});
this._register(this._commentEditorActions);
this._commentEditorActions.setActions(editorMenu, true);
}
private get isReplyExpanded(): boolean {
return this.form.classList.contains('expand');
}
@@ -49,7 +49,6 @@ export class SimpleCommentEditor extends CodeEditorWidget {
@ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService,
) {
const codeEditorWidgetOptions: ICodeEditorWidgetOptions = {
isSimpleWidget: true,
contributions: <IEditorContributionDescription[]>[
{ id: MenuPreventer.ID, ctor: MenuPreventer, instantiation: EditorContributionInstantiation.BeforeFirstInteraction },
{ id: ContextMenuController.ID, ctor: ContextMenuController, instantiation: EditorContributionInstantiation.BeforeFirstInteraction },
@@ -148,6 +148,12 @@ const apiMenus: IAPIMenu[] = [
id: MenuId.ViewItemContext,
description: localize('view.itemContext', "The contributed view item context menu")
},
{
key: 'comments/comment/editorActions',
id: MenuId.CommentEditorActions,
description: localize('commentThread.editorActions', "The contributed comment editor actions"),
proposed: 'contribCommentEditorActionsMenu'
},
{
key: 'comments/commentThread/title',
id: MenuId.CommentThreadTitle,
@@ -9,6 +9,7 @@ export const allApiProposals = Object.freeze({
authSession: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.authSession.d.ts',
codiconDecoration: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.codiconDecoration.d.ts',
commentsResolvedState: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.commentsResolvedState.d.ts',
contribCommentEditorActionsMenu: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribCommentEditorActionsMenu.d.ts',
contribCommentPeekContext: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribCommentPeekContext.d.ts',
contribCommentThreadAdditionalMenu: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribCommentThreadAdditionalMenu.d.ts',
contribEditSessions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribEditSessions.d.ts',
@@ -0,0 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// empty placeholder declaration for the `comments/comment/editorActions` menu