Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/comments/browser/commentGlyphWidget.ts
5272 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as nls from '../../../../nls.js';
7
import { Color } from '../../../../base/common/color.js';
8
import { ContentWidgetPositionPreference, ICodeEditor, IContentWidgetPosition } from '../../../../editor/browser/editorBrowser.js';
9
import { IModelDecorationOptions, OverviewRulerLane } from '../../../../editor/common/model.js';
10
import { ModelDecorationOptions } from '../../../../editor/common/model/textModel.js';
11
import { darken, editorBackground, editorForeground, listInactiveSelectionBackground, opaque, registerColor } from '../../../../platform/theme/common/colorRegistry.js';
12
import { themeColorFromId } from '../../../../platform/theme/common/themeService.js';
13
import { IEditorDecorationsCollection } from '../../../../editor/common/editorCommon.js';
14
import { CommentThreadState } from '../../../../editor/common/languages.js';
15
import { Disposable, toDisposable } from '../../../../base/common/lifecycle.js';
16
import { Emitter } from '../../../../base/common/event.js';
17
18
export const overviewRulerCommentingRangeForeground = registerColor('editorGutter.commentRangeForeground', { dark: opaque(listInactiveSelectionBackground, editorBackground), light: darken(opaque(listInactiveSelectionBackground, editorBackground), .05), hcDark: Color.white, hcLight: Color.black }, nls.localize('editorGutterCommentRangeForeground', 'Editor gutter decoration color for commenting ranges. This color should be opaque.'));
19
const overviewRulerCommentForeground = registerColor('editorOverviewRuler.commentForeground', overviewRulerCommentingRangeForeground, nls.localize('editorOverviewRuler.commentForeground', 'Editor overview ruler decoration color for resolved comments. This color should be opaque.'));
20
const overviewRulerCommentUnresolvedForeground = registerColor('editorOverviewRuler.commentUnresolvedForeground', overviewRulerCommentForeground, nls.localize('editorOverviewRuler.commentUnresolvedForeground', 'Editor overview ruler decoration color for unresolved comments. This color should be opaque.'));
21
const overviewRulerCommentDraftForeground = registerColor('editorOverviewRuler.commentDraftForeground', overviewRulerCommentUnresolvedForeground, nls.localize('editorOverviewRuler.commentDraftForeground', 'Editor overview ruler decoration color for comment threads with draft comments. This color should be opaque.'));
22
23
const editorGutterCommentGlyphForeground = registerColor('editorGutter.commentGlyphForeground', { dark: editorForeground, light: editorForeground, hcDark: Color.black, hcLight: Color.white }, nls.localize('editorGutterCommentGlyphForeground', 'Editor gutter decoration color for commenting glyphs.'));
24
registerColor('editorGutter.commentUnresolvedGlyphForeground', editorGutterCommentGlyphForeground, nls.localize('editorGutterCommentUnresolvedGlyphForeground', 'Editor gutter decoration color for commenting glyphs for unresolved comment threads.'));
25
registerColor('editorGutter.commentDraftGlyphForeground', editorGutterCommentGlyphForeground, nls.localize('editorGutterCommentDraftGlyphForeground', 'Editor gutter decoration color for commenting glyphs for comment threads with draft comments.'));
26
27
export class CommentGlyphWidget extends Disposable {
28
public static description = 'comment-glyph-widget';
29
private _lineNumber!: number;
30
private _editor: ICodeEditor;
31
private _threadState: CommentThreadState | undefined;
32
private _threadHasDraft: boolean = false;
33
private readonly _commentsDecorations: IEditorDecorationsCollection;
34
private _commentsOptions: ModelDecorationOptions;
35
36
private readonly _onDidChangeLineNumber = this._register(new Emitter<number>());
37
public readonly onDidChangeLineNumber = this._onDidChangeLineNumber.event;
38
39
constructor(editor: ICodeEditor, lineNumber: number) {
40
super();
41
this._commentsOptions = this.createDecorationOptions();
42
this._editor = editor;
43
this._commentsDecorations = this._editor.createDecorationsCollection();
44
this._register(this._commentsDecorations.onDidChange(e => {
45
const range = (this._commentsDecorations.length > 0 ? this._commentsDecorations.getRange(0) : null);
46
if (range && range.endLineNumber !== this._lineNumber) {
47
this._lineNumber = range.endLineNumber;
48
this._onDidChangeLineNumber.fire(this._lineNumber);
49
}
50
}));
51
this._register(toDisposable(() => this._commentsDecorations.clear()));
52
this.setLineNumber(lineNumber);
53
}
54
55
private createDecorationOptions(): ModelDecorationOptions {
56
// Priority: draft > unresolved > resolved
57
let className: string;
58
if (this._threadHasDraft) {
59
className = 'comment-range-glyph comment-thread-draft';
60
} else {
61
const unresolved = this._threadState === CommentThreadState.Unresolved;
62
className = `comment-range-glyph comment-thread${unresolved ? '-unresolved' : ''}`;
63
}
64
65
const decorationOptions: IModelDecorationOptions = {
66
description: CommentGlyphWidget.description,
67
isWholeLine: true,
68
overviewRuler: {
69
color: themeColorFromId(this._threadHasDraft ? overviewRulerCommentDraftForeground :
70
(this._threadState === CommentThreadState.Unresolved ? overviewRulerCommentUnresolvedForeground : overviewRulerCommentForeground)),
71
position: OverviewRulerLane.Center
72
},
73
collapseOnReplaceEdit: true,
74
linesDecorationsClassName: className
75
};
76
77
return ModelDecorationOptions.createDynamic(decorationOptions);
78
}
79
80
setThreadState(state: CommentThreadState | undefined, hasDraft: boolean = false): void {
81
if (this._threadState !== state || this._threadHasDraft !== hasDraft) {
82
this._threadState = state;
83
this._threadHasDraft = hasDraft;
84
this._commentsOptions = this.createDecorationOptions();
85
this._updateDecorations();
86
}
87
}
88
89
private _updateDecorations(): void {
90
const commentsDecorations = [{
91
range: {
92
startLineNumber: this._lineNumber, startColumn: 1,
93
endLineNumber: this._lineNumber, endColumn: 1
94
},
95
options: this._commentsOptions
96
}];
97
98
this._commentsDecorations.set(commentsDecorations);
99
}
100
101
setLineNumber(lineNumber: number): void {
102
this._lineNumber = lineNumber;
103
this._updateDecorations();
104
}
105
106
getPosition(): IContentWidgetPosition {
107
const range = (this._commentsDecorations.length > 0 ? this._commentsDecorations.getRange(0) : null);
108
109
return {
110
position: {
111
lineNumber: range ? range.endLineNumber : this._lineNumber,
112
column: 1
113
},
114
preference: [ContentWidgetPositionPreference.EXACT]
115
};
116
}
117
}
118
119