Skip to content

Commit

Permalink
Add support for editing comments, #58078
Browse files Browse the repository at this point in the history
  • Loading branch information
Rachel Macfarlane authored Sep 17, 2018
1 parent ec058d3 commit 1d1105e
Show file tree
Hide file tree
Showing 9 changed files with 444 additions and 107 deletions.
4 changes: 2 additions & 2 deletions src/vs/editor/common/modes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1008,6 +1008,7 @@ export interface Comment {
readonly body: IMarkdownString;
readonly userName: string;
readonly gravatar: string;
readonly canEdit?: boolean;
readonly command?: Command;
}

Expand Down Expand Up @@ -1039,6 +1040,7 @@ export interface DocumentCommentProvider {
provideDocumentComments(resource: URI, token: CancellationToken): Promise<CommentInfo>;
createNewCommentThread(resource: URI, range: Range, text: string, token: CancellationToken): Promise<CommentThread>;
replyToCommentThread(resource: URI, range: Range, thread: CommentThread, text: string, token: CancellationToken): Promise<CommentThread>;
editComment(resource: URI, comment: Comment, text: string, token: CancellationToken): Promise<Comment>;
onDidChangeCommentThreads(): Event<CommentThreadChangedEvent>;
}

Expand All @@ -1047,8 +1049,6 @@ export interface DocumentCommentProvider {
*/
export interface WorkspaceCommentProvider {
provideWorkspaceComments(token: CancellationToken): Promise<CommentThread[]>;
createNewCommentThread(resource: URI, range: Range, text: string, token: CancellationToken): Promise<CommentThread>;
replyToCommentThread(resource: URI, range: Range, thread: CommentThread, text: string, token: CancellationToken): Promise<CommentThread>;
onDidChangeCommentThreads(): Event<CommentThreadChangedEvent>;
}

Expand Down
55 changes: 55 additions & 0 deletions src/vs/vscode.proposed.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -656,10 +656,37 @@ declare module 'vscode' {
}

interface Comment {
/**
* The id of the comment
*/
commentId: string;

/**
* The text of the comment
*/
body: MarkdownString;

/**
* The display name of the user who created the comment
*/
userName: string;

/**
* The avatar src of the user who created the comment
*/
gravatar: string;

/**
* Whether the current user has permission to edit the comment.
*
* This will be treated as false if the comment is provided by a `WorkspaceCommentProvider`, or
* if it is provided by a `DocumentCommentProvider` and no `editComment` method is given.
*/
canEdit?: boolean;

/**
* The command to be executed if the comment is selected in the Comments Panel
*/
command?: Command;
}

Expand All @@ -681,14 +708,42 @@ declare module 'vscode' {
}

interface DocumentCommentProvider {
/**
* Provide the commenting ranges and comment threads for the given document. The comments are displayed within the editor.
*/
provideDocumentComments(document: TextDocument, token: CancellationToken): Promise<CommentInfo>;

/**
* Called when a user adds a new comment thread in the document at the specified range, with body text.
*/
createNewCommentThread(document: TextDocument, range: Range, text: string, token: CancellationToken): Promise<CommentThread>;

/**
* Called when a user replies to a new comment thread in the document at the specified range, with body text.
*/
replyToCommentThread(document: TextDocument, range: Range, commentThread: CommentThread, text: string, token: CancellationToken): Promise<CommentThread>;

/**
* Called when a user edits the comment body to the be new text text.
*/
editComment?(document: TextDocument, comment: Comment, text: string, token: CancellationToken): Promise<Comment>;

/**
* Notify of updates to comment threads.
*/
onDidChangeCommentThreads: Event<CommentThreadChangedEvent>;
}

interface WorkspaceCommentProvider {
/**
* Provide all comments for the workspace. Comments are shown within the comments panel. Selecting a comment
* from the panel runs the comment's command.
*/
provideWorkspaceComments(token: CancellationToken): Promise<CommentThread[]>;

/**
* Notify of updates to comment threads.
*/
onDidChangeCommentThreads: Event<CommentThreadChangedEvent>;
}

Expand Down
3 changes: 3 additions & 0 deletions src/vs/workbench/api/electron-browser/mainThreadComments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ export class MainThreadComments extends Disposable implements MainThreadComments
},
replyToCommentThread: async (uri, range, thread, text, token) => {
return this._proxy.$replyToCommentThread(handle, uri, range, thread, text);
},
editComment: async (uri, comment, text, token) => {
return this._proxy.$editComment(handle, uri, comment, text);
}
}
);
Expand Down
1 change: 1 addition & 0 deletions src/vs/workbench/api/node/extHost.protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -995,6 +995,7 @@ export interface ExtHostCommentsShape {
$provideDocumentComments(handle: number, document: UriComponents): Thenable<modes.CommentInfo>;
$createNewCommentThread(handle: number, document: UriComponents, range: IRange, text: string): Thenable<modes.CommentThread>;
$replyToCommentThread(handle: number, document: UriComponents, range: IRange, commentThread: modes.CommentThread, text: string): Thenable<modes.CommentThread>;
$editComment(handle: number, document: UriComponents, comment: modes.Comment, text: string): Thenable<modes.Comment>;
$provideWorkspaceComments(handle: number): Thenable<modes.CommentThread[]>;
}

Expand Down
49 changes: 32 additions & 17 deletions src/vs/workbench/api/node/extHostComments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ export class ExtHostComments implements ExtHostCommentsShape {
return TPromise.as(null);
}

const provider = this._documentProviders.get(handle);
return asThenable(() => {
let provider = this._documentProviders.get(handle);
return provider.createNewCommentThread(data.document, ran, text, CancellationToken.None);
}).then(commentThread => commentThread ? convertToCommentThread(commentThread, this._commandsConverter) : null);
}).then(commentThread => commentThread ? convertToCommentThread(provider, commentThread, this._commandsConverter) : null);
}

$replyToCommentThread(handle: number, uri: UriComponents, range: IRange, thread: modes.CommentThread, text: string): Thenable<modes.CommentThread> {
Expand All @@ -87,10 +87,23 @@ export class ExtHostComments implements ExtHostCommentsShape {
return TPromise.as(null);
}

const provider = this._documentProviders.get(handle);
return asThenable(() => {
let provider = this._documentProviders.get(handle);
return provider.replyToCommentThread(data.document, ran, convertFromCommentThread(thread), text, CancellationToken.None);
}).then(commentThread => commentThread ? convertToCommentThread(commentThread, this._commandsConverter) : null);
}).then(commentThread => commentThread ? convertToCommentThread(provider, commentThread, this._commandsConverter) : null);
}

$editComment(handle: number, uri: UriComponents, comment: modes.Comment, text: string): Thenable<modes.Comment> {
const data = this._documents.getDocumentData(URI.revive(uri));

if (!data || !data.document) {
throw new Error('Unable to retrieve document from URI');
}

const provider = this._documentProviders.get(handle);
return asThenable(() => {
return provider.editComment(data.document, convertFromComment(comment), text, CancellationToken.None);
}).then(comment => convertToComment(provider, comment, this._commandsConverter));
}

$provideDocumentComments(handle: number, uri: UriComponents): Thenable<modes.CommentInfo> {
Expand All @@ -99,11 +112,10 @@ export class ExtHostComments implements ExtHostCommentsShape {
return TPromise.as(null);
}

const provider = this._documentProviders.get(handle);
return asThenable(() => {
let provider = this._documentProviders.get(handle);
return provider.provideDocumentComments(data.document, CancellationToken.None);
})
.then(commentInfo => commentInfo ? convertCommentInfo(handle, commentInfo, this._commandsConverter) : null);
}).then(commentInfo => commentInfo ? convertCommentInfo(handle, provider, commentInfo, this._commandsConverter) : null);
}

$provideWorkspaceComments(handle: number): Thenable<modes.CommentThread[]> {
Expand All @@ -115,7 +127,7 @@ export class ExtHostComments implements ExtHostCommentsShape {
return asThenable(() => {
return provider.provideWorkspaceComments(CancellationToken.None);
}).then(comments =>
comments.map(x => convertToCommentThread(x, this._commandsConverter)
comments.map(comment => convertToCommentThread(provider, comment, this._commandsConverter)
));
}

Expand All @@ -124,28 +136,28 @@ export class ExtHostComments implements ExtHostCommentsShape {

this._proxy.$onDidCommentThreadsChange(handle, {
owner: handle,
changed: event.changed.map(x => convertToCommentThread(x, this._commandsConverter)),
added: event.added.map(x => convertToCommentThread(x, this._commandsConverter)),
removed: event.removed.map(x => convertToCommentThread(x, this._commandsConverter))
changed: event.changed.map(thread => convertToCommentThread(provider, thread, this._commandsConverter)),
added: event.added.map(thread => convertToCommentThread(provider, thread, this._commandsConverter)),
removed: event.removed.map(thread => convertToCommentThread(provider, thread, this._commandsConverter))
});
});
}
}

function convertCommentInfo(owner: number, vscodeCommentInfo: vscode.CommentInfo, commandsConverter: CommandsConverter): modes.CommentInfo {
function convertCommentInfo(owner: number, provider: vscode.DocumentCommentProvider, vscodeCommentInfo: vscode.CommentInfo, commandsConverter: CommandsConverter): modes.CommentInfo {
return {
owner: owner,
threads: vscodeCommentInfo.threads.map(x => convertToCommentThread(x, commandsConverter)),
threads: vscodeCommentInfo.threads.map(x => convertToCommentThread(provider, x, commandsConverter)),
commentingRanges: vscodeCommentInfo.commentingRanges ? vscodeCommentInfo.commentingRanges.map(range => extHostTypeConverter.Range.from(range)) : []
};
}

function convertToCommentThread(vscodeCommentThread: vscode.CommentThread, commandsConverter: CommandsConverter): modes.CommentThread {
function convertToCommentThread(provider: vscode.DocumentCommentProvider | vscode.WorkspaceCommentProvider, vscodeCommentThread: vscode.CommentThread, commandsConverter: CommandsConverter): modes.CommentThread {
return {
threadId: vscodeCommentThread.threadId,
resource: vscodeCommentThread.resource.toString(),
range: extHostTypeConverter.Range.from(vscodeCommentThread.range),
comments: vscodeCommentThread.comments.map(comment => convertToComment(comment, commandsConverter)),
comments: vscodeCommentThread.comments.map(comment => convertToComment(provider, comment, commandsConverter)),
collapsibleState: vscodeCommentThread.collapsibleState
};
}
Expand All @@ -165,16 +177,19 @@ function convertFromComment(comment: modes.Comment): vscode.Comment {
commentId: comment.commentId,
body: extHostTypeConverter.MarkdownString.to(comment.body),
userName: comment.userName,
gravatar: comment.gravatar
gravatar: comment.gravatar,
canEdit: comment.canEdit
};
}

function convertToComment(vscodeComment: vscode.Comment, commandsConverter: CommandsConverter): modes.Comment {
function convertToComment(provider: vscode.DocumentCommentProvider | vscode.WorkspaceCommentProvider, vscodeComment: vscode.Comment, commandsConverter: CommandsConverter): modes.Comment {
const canEdit = !!(provider as vscode.DocumentCommentProvider).editComment && vscodeComment.canEdit;
return {
commentId: vscodeComment.commentId,
body: extHostTypeConverter.MarkdownString.from(vscodeComment.body),
userName: vscodeComment.userName,
gravatar: vscodeComment.gravatar,
canEdit: canEdit,
command: vscodeComment.command ? commandsConverter.toInternal(vscodeComment.command) : null
};
}
Loading

0 comments on commit 1d1105e

Please sign in to comment.