Change:
VSCode Version: 1.36.0 OS Version: Windows 10 Repro steps: Live Share extension 1.0.488, start a collaboration session two comment threads on a single line. Comment on a line, 3 for example Comment on a second line, 4 for example Delete line 3 Now there are two comment threads on line 3 (the line that moved up from 4) /Collapse the comments with the marker Collapsing/opening such comments might need a rework. Currently I can collapse each individually, and if all are collapsed (or all open), the box on the gray line opens (or closes) all threads. However, if only some of the threads are collapsed, the gray box toggles between the set of open threads and the threads which were collapsed. It never collapses all threads to return to code, and requires each remaining thread to be collapsed individually. Originally reported in Live Share issue
As I was just about to file the same thing, here is the screencast I created for illustration: !
I agree the current behavior is a bit confusing. Clicking in the gutter is a common way to collapse open comments. However, the workflow fails when multiple comments are on the same line. This forces the user to think and use the alternative workflow (top-right icon). Suggested behavior: if at least one comment is expanded, collapse all comments on the line otherwise, expand all the comments The condition could also be reversed (expand if the line has both expanded and collapsed comments).
Since we just came across the relevant code again in another context: clicks on the gutter icon currently toggle the collapsible states for all threads on that line independently here: already exists as a private property, if there was a public getter for it, behavior like the one suggested by above could probably be implemented very locally in the location I linked to above. let us know if that sounds reasonable and we can make a PR.
yes, this sounds reasonable to me. l would accept a PR!
I opened .

Discussion:
return this._commentThread; } <ins> public get expanded(): boolean | undefined { return this._isExpanded; } </ins> private _commentOptions: languages.CommentOptions | undefined; constructor(

this.commentService.disposeCommentThread(this.owner, this._commentThread.threadId); } <del> public collapse(): Promise<void> { </del> <ins> public collapse() { </ins> this._commentThread.collapsibleState = languages.CommentThreadCollapsibleState.Collapsed; <del> if (this._commentThread.comments && this._commentThread.comments.length === 0) { this.deleteCommentThread(); return Promise.resolve(); } this.hide(); return Promise.resolve(); </del> } <del> public expand(): Promise<void> { </del> <ins> public expand() { </ins> this._commentThread.collapsibleState = languages.CommentThreadCollapsibleState.Expanded; <del> this.show(this.arrowPosition(this._commentThread.range), 2); return Promise.resolve(); </del> } public getGlyphPosition(): number {

// The widget's position is undefined until the widget has been displayed, so rely on the glyph position instead const existingCommentsAtLine = this._commentWidgets.filter(widget => widget.getGlyphPosition() === commentRange.endLineNumber); if (existingCommentsAtLine.length) { <del> existingCommentsAtLine.forEach(widget => widget.toggleExpand()); </del> <ins> const allExpanded = existingCommentsAtLine.every(widget => widget.expanded); existingCommentsAtLine.forEach(allExpanded ? widget => widget.collapse() : widget => widget.expand()); </ins> this.processNextThreadToAdd(); return; } else {