mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 04:49:35 +00:00
Merge branch 'main' into npm-extension-bun-package-manager
This commit is contained in:
commit
fca65094bf
|
@ -697,7 +697,7 @@
|
|||
{
|
||||
"command": "git.timeline.openCommit",
|
||||
"title": "%command.timelineOpenCommit%",
|
||||
"icon": "$(wand)",
|
||||
"icon": "$(search)",
|
||||
"category": "Git"
|
||||
},
|
||||
{
|
||||
|
|
|
@ -34,6 +34,7 @@ import * as typeh from 'vs/workbench/contrib/typeHierarchy/common/typeHierarchy'
|
|||
import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers';
|
||||
import { ExtHostContext, ExtHostLanguageFeaturesShape, ICallHierarchyItemDto, ICodeActionDto, ICodeActionProviderMetadataDto, IdentifiableInlineCompletion, IdentifiableInlineCompletions, IDocumentDropEditProviderMetadata, IDocumentFilterDto, IIndentationRuleDto, IInlayHintDto, ILanguageConfigurationDto, ILanguageWordDefinitionDto, ILinkDto, ILocationDto, ILocationLinkDto, IOnEnterRuleDto, IPasteEditProviderMetadataDto, IRegExpDto, ISignatureHelpProviderMetadataDto, ISuggestDataDto, ISuggestDataDtoField, ISuggestResultDtoField, ITypeHierarchyItemDto, IWorkspaceSymbolDto, MainContext, MainThreadLanguageFeaturesShape } from '../common/extHost.protocol';
|
||||
import { USUAL_WORD_SEPARATORS } from 'vs/editor/common/core/wordHelper';
|
||||
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadLanguageFeatures)
|
||||
export class MainThreadLanguageFeatures extends Disposable implements MainThreadLanguageFeaturesShape {
|
||||
|
@ -308,15 +309,12 @@ export class MainThreadLanguageFeatures extends Disposable implements MainThread
|
|||
});
|
||||
|
||||
const res = this._proxy.$provideDocumentHighlights(handle, model.uri, position, token);
|
||||
if (!res) {
|
||||
return Promise.resolve(new Map<URI, languages.DocumentHighlight[]>());
|
||||
}
|
||||
|
||||
return res.then(data => {
|
||||
const result = new Map<URI, languages.DocumentHighlight[]>();
|
||||
if (data) {
|
||||
result.set(model.uri, data);
|
||||
if (isFalsyOrEmpty(data) || !data) {
|
||||
return result;
|
||||
}
|
||||
result.set(model.uri, data);
|
||||
|
||||
if (!word) {
|
||||
return result;
|
||||
|
|
|
@ -42,6 +42,7 @@ export interface INotebookCommentInfo {
|
|||
|
||||
export interface IWorkspaceCommentThreadsEvent {
|
||||
ownerId: string;
|
||||
ownerLabel: string;
|
||||
commentThreads: CommentThread[];
|
||||
}
|
||||
|
||||
|
@ -51,6 +52,7 @@ export interface INotebookCommentThreadChangedEvent extends CommentThreadChanged
|
|||
|
||||
export interface ICommentController {
|
||||
id: string;
|
||||
label: string;
|
||||
features: {
|
||||
reactionGroup?: CommentReaction[];
|
||||
reactionHandler?: boolean;
|
||||
|
@ -186,8 +188,13 @@ export class CommentService extends Disposable implements ICommentService {
|
|||
this.logService.debug(`Comments: URIs of continue on comments from storage ${commentsToRestore.map(thread => thread.uri.toString()).join(', ')}.`);
|
||||
const changedOwners = this._addContinueOnComments(commentsToRestore, this._continueOnComments);
|
||||
for (const owner of changedOwners) {
|
||||
const control = this._commentControls.get(owner);
|
||||
if (!control) {
|
||||
continue;
|
||||
}
|
||||
const evt: ICommentThreadChangedEvent = {
|
||||
owner,
|
||||
ownerLabel: control.label,
|
||||
pending: this._continueOnComments.get(owner) || [],
|
||||
added: [],
|
||||
removed: [],
|
||||
|
@ -269,11 +276,17 @@ export class CommentService extends Disposable implements ICommentService {
|
|||
if (commentsByResource.length) {
|
||||
this._workspaceHasCommenting.set(true);
|
||||
}
|
||||
this._onDidSetAllCommentThreads.fire({ ownerId: owner, commentThreads: commentsByResource });
|
||||
const control = this._commentControls.get(owner);
|
||||
if (control) {
|
||||
this._onDidSetAllCommentThreads.fire({ ownerId: owner, ownerLabel: control.label, commentThreads: commentsByResource });
|
||||
}
|
||||
}
|
||||
|
||||
removeWorkspaceComments(owner: string): void {
|
||||
this._onDidSetAllCommentThreads.fire({ ownerId: owner, commentThreads: [] });
|
||||
const control = this._commentControls.get(owner);
|
||||
if (control) {
|
||||
this._onDidSetAllCommentThreads.fire({ ownerId: owner, ownerLabel: control.label, commentThreads: [] });
|
||||
}
|
||||
}
|
||||
|
||||
registerCommentController(owner: string, commentControl: ICommentController): void {
|
||||
|
@ -330,8 +343,11 @@ export class CommentService extends Disposable implements ICommentService {
|
|||
}
|
||||
|
||||
updateComments(ownerId: string, event: CommentThreadChangedEvent<IRange>): void {
|
||||
const evt: ICommentThreadChangedEvent = Object.assign({}, event, { owner: ownerId });
|
||||
this._onDidUpdateCommentThreads.fire(evt);
|
||||
const control = this._commentControls.get(ownerId);
|
||||
if (control) {
|
||||
const evt: ICommentThreadChangedEvent = Object.assign({}, event, { owner: ownerId, ownerLabel: control.label });
|
||||
this._onDidUpdateCommentThreads.fire(evt);
|
||||
}
|
||||
}
|
||||
|
||||
updateNotebookComments(ownerId: string, event: CommentThreadChangedEvent<ICellRange>): void {
|
||||
|
|
|
@ -38,6 +38,8 @@ export const COMMENTS_VIEW_TITLE: ILocalizedString = nls.localize2('comments.vie
|
|||
|
||||
interface IResourceTemplateData {
|
||||
resourceLabel: IResourceLabel;
|
||||
separator: HTMLElement;
|
||||
owner: HTMLElement;
|
||||
}
|
||||
|
||||
interface ICommentThreadTemplateData {
|
||||
|
@ -95,12 +97,23 @@ export class ResourceWithCommentsRenderer implements IListRenderer<ITreeNode<Res
|
|||
renderTemplate(container: HTMLElement) {
|
||||
const labelContainer = dom.append(container, dom.$('.resource-container'));
|
||||
const resourceLabel = this.labels.create(labelContainer);
|
||||
const separator = dom.append(labelContainer, dom.$('.separator'));
|
||||
const owner = labelContainer.appendChild(dom.$('.owner'));
|
||||
|
||||
return { resourceLabel };
|
||||
return { resourceLabel, owner, separator };
|
||||
}
|
||||
|
||||
renderElement(node: ITreeNode<ResourceWithCommentThreads>, index: number, templateData: IResourceTemplateData, height: number | undefined): void {
|
||||
templateData.resourceLabel.setFile(node.element.resource);
|
||||
templateData.separator.innerText = '\u00b7';
|
||||
|
||||
if (node.element.ownerLabel) {
|
||||
templateData.owner.innerText = node.element.ownerLabel;
|
||||
templateData.separator.style.display = 'inline';
|
||||
} else {
|
||||
templateData.owner.innerText = '';
|
||||
templateData.separator.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
disposeTemplate(templateData: IResourceTemplateData): void {
|
||||
|
@ -337,7 +350,6 @@ export class CommentsList extends WorkbenchObjectTree<CommentsModel | ResourceWi
|
|||
options: ICommentsListOptions,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IListService listService: IListService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
) {
|
||||
|
|
|
@ -456,7 +456,7 @@ export class CommentsPanel extends FilterViewPane implements ICommentsView {
|
|||
|
||||
private onAllCommentsChanged(e: IWorkspaceCommentThreadsEvent): void {
|
||||
this.cachedFilterStats = undefined;
|
||||
this.commentsModel.setCommentThreads(e.ownerId, e.commentThreads);
|
||||
this.commentsModel.setCommentThreads(e.ownerId, e.ownerLabel, e.commentThreads);
|
||||
this.totalComments += e.commentThreads.length;
|
||||
|
||||
let unresolved = 0;
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
}
|
||||
|
||||
.comments-panel .comments-panel-container .tree-container .comment-thread-container .reply-detail,
|
||||
.comments-panel .comments-panel-container .tree-container .resource-container .owner,
|
||||
.comments-panel .comments-panel-container .tree-container .comment-thread-container .timestamp {
|
||||
display: block;
|
||||
overflow: hidden;
|
||||
|
@ -84,7 +85,11 @@
|
|||
font-family: var(--monaco-monospace-font);
|
||||
}
|
||||
|
||||
.comments-panel .comments-panel-container .tree-container .comment-thread-container .separator {
|
||||
.comments-panel .comments-panel-container .tree-container .monaco-icon-label {
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.comments-panel .comments-panel-container .tree-container .separator {
|
||||
padding-right: 5px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import { localize } from 'vs/nls';
|
|||
|
||||
export interface ICommentThreadChangedEvent extends CommentThreadChangedEvent<IRange> {
|
||||
owner: string;
|
||||
ownerLabel: string;
|
||||
}
|
||||
|
||||
export class CommentNode {
|
||||
|
@ -41,6 +42,7 @@ export class CommentNode {
|
|||
export class ResourceWithCommentThreads {
|
||||
id: string;
|
||||
owner: string;
|
||||
ownerLabel: string | undefined;
|
||||
commentThreads: CommentNode[]; // The top level comments on the file. Replys are nested under each node.
|
||||
resource: URI;
|
||||
|
||||
|
@ -66,28 +68,35 @@ export class ResourceWithCommentThreads {
|
|||
|
||||
export class CommentsModel {
|
||||
resourceCommentThreads: ResourceWithCommentThreads[];
|
||||
commentThreadsMap: Map<string, ResourceWithCommentThreads[]>;
|
||||
commentThreadsMap: Map<string, { resourceWithCommentThreads: ResourceWithCommentThreads[]; ownerLabel?: string }>;
|
||||
|
||||
constructor() {
|
||||
this.resourceCommentThreads = [];
|
||||
this.commentThreadsMap = new Map<string, ResourceWithCommentThreads[]>();
|
||||
this.commentThreadsMap = new Map<string, { resourceWithCommentThreads: ResourceWithCommentThreads[]; ownerLabel: string }>();
|
||||
}
|
||||
|
||||
private updateResourceCommentThreads() {
|
||||
this.resourceCommentThreads = [...this.commentThreadsMap.values()].flat();
|
||||
const includeLabel = this.commentThreadsMap.size > 1;
|
||||
this.resourceCommentThreads = [...this.commentThreadsMap.values()].map(value => {
|
||||
return value.resourceWithCommentThreads.map(resource => {
|
||||
resource.ownerLabel = includeLabel ? value.ownerLabel : undefined;
|
||||
return resource;
|
||||
}).flat();
|
||||
}).flat();
|
||||
this.resourceCommentThreads.sort((a, b) => {
|
||||
return a.resource.toString() > b.resource.toString() ? 1 : -1;
|
||||
});
|
||||
}
|
||||
|
||||
public setCommentThreads(owner: string, commentThreads: CommentThread[]): void {
|
||||
this.commentThreadsMap.set(owner, this.groupByResource(owner, commentThreads));
|
||||
public setCommentThreads(owner: string, ownerLabel: string, commentThreads: CommentThread[]): void {
|
||||
this.commentThreadsMap.set(owner, { ownerLabel, resourceWithCommentThreads: this.groupByResource(owner, commentThreads) });
|
||||
this.updateResourceCommentThreads();
|
||||
}
|
||||
|
||||
public deleteCommentsByOwner(owner?: string): void {
|
||||
if (owner) {
|
||||
this.commentThreadsMap.set(owner, []);
|
||||
const existingOwner = this.commentThreadsMap.get(owner);
|
||||
this.commentThreadsMap.set(owner, { ownerLabel: existingOwner?.ownerLabel, resourceWithCommentThreads: [] });
|
||||
} else {
|
||||
this.commentThreadsMap.clear();
|
||||
}
|
||||
|
@ -95,9 +104,9 @@ export class CommentsModel {
|
|||
}
|
||||
|
||||
public updateCommentThreads(event: ICommentThreadChangedEvent): boolean {
|
||||
const { owner, removed, changed, added } = event;
|
||||
const { owner, ownerLabel, removed, changed, added } = event;
|
||||
|
||||
const threadsForOwner = this.commentThreadsMap.get(owner) || [];
|
||||
const threadsForOwner = this.commentThreadsMap.get(owner)?.resourceWithCommentThreads || [];
|
||||
|
||||
removed.forEach(thread => {
|
||||
// Find resource that has the comment thread
|
||||
|
@ -145,7 +154,7 @@ export class CommentsModel {
|
|||
}
|
||||
});
|
||||
|
||||
this.commentThreadsMap.set(owner, threadsForOwner);
|
||||
this.commentThreadsMap.set(owner, { ownerLabel, resourceWithCommentThreads: threadsForOwner });
|
||||
this.updateResourceCommentThreads();
|
||||
|
||||
return removed.length > 0 || changed.length > 0 || added.length > 0;
|
||||
|
|
|
@ -7,8 +7,8 @@ import * as assert from 'assert';
|
|||
import { workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { IRange, Range } from 'vs/editor/common/core/range';
|
||||
import { CommentsPanel } from 'vs/workbench/contrib/comments/browser/commentsView';
|
||||
import { CommentService, ICommentService } from 'vs/workbench/contrib/comments/browser/commentService';
|
||||
import { Comment, CommentInput, CommentThread, CommentThreadCollapsibleState, CommentThreadState } from 'vs/editor/common/languages';
|
||||
import { CommentService, ICommentController, ICommentInfo, ICommentService, INotebookCommentInfo } from 'vs/workbench/contrib/comments/browser/commentService';
|
||||
import { Comment, CommentInput, CommentReaction, CommentThread, CommentThreadCollapsibleState, CommentThreadState } from 'vs/editor/common/languages';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
import { IViewContainerModel, IViewDescriptor, IViewDescriptorService, ViewContainer, ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
|
@ -17,6 +17,8 @@ import { TestConfigurationService } from 'vs/platform/configuration/test/common/
|
|||
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
|
||||
class TestCommentThread implements CommentThread<IRange> {
|
||||
isDocumentCommentThread(): this is CommentThread<IRange> {
|
||||
|
@ -44,6 +46,31 @@ class TestCommentThread implements CommentThread<IRange> {
|
|||
contextValue: string | undefined = undefined;
|
||||
}
|
||||
|
||||
class TestCommentController implements ICommentController {
|
||||
id: string = 'test';
|
||||
label: string = 'Test Comments';
|
||||
features = {};
|
||||
createCommentThreadTemplate(resource: UriComponents, range: IRange | undefined): Promise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
updateCommentThreadTemplate(threadHandle: number, range: IRange): Promise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
deleteCommentThreadMain(commentThreadId: string): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
toggleReaction(uri: URI, thread: CommentThread<IRange>, comment: Comment, reaction: CommentReaction, token: CancellationToken): Promise<void> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
getDocumentComments(resource: URI, token: CancellationToken): Promise<ICommentInfo> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
getNotebookComments(resource: URI, token: CancellationToken): Promise<INotebookCommentInfo> {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class TestViewDescriptorService implements Partial<IViewDescriptorService> {
|
||||
getViewLocationById(id: string): ViewContainerLocation | null {
|
||||
return ViewContainerLocation.Panel;
|
||||
|
@ -91,6 +118,7 @@ suite('Comments View', function () {
|
|||
instantiationService.stub(IViewDescriptorService, new TestViewDescriptorService());
|
||||
commentService = instantiationService.createInstance(CommentService);
|
||||
instantiationService.stub(ICommentService, commentService);
|
||||
commentService.registerCommentController('test', new TestCommentController());
|
||||
});
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue