Path: blob/main/src/vs/workbench/contrib/comments/browser/simpleCommentEditor.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { EditorOption, IEditorOptions } from '../../../../editor/common/config/editorOptions.js';6import { EditorAction, EditorContributionInstantiation, EditorExtensionsRegistry, IEditorContributionDescription } from '../../../../editor/browser/editorExtensions.js';7import { ICodeEditorService } from '../../../../editor/browser/services/codeEditorService.js';8import { CodeEditorWidget, ICodeEditorWidgetOptions } from '../../../../editor/browser/widget/codeEditor/codeEditorWidget.js';9import { IContextKeyService, RawContextKey, IContextKey } from '../../../../platform/contextkey/common/contextkey.js';10import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';11import { ICommandService } from '../../../../platform/commands/common/commands.js';1213// Allowed Editor Contributions:14import { MenuPreventer } from '../../codeEditor/browser/menuPreventer.js';15import { EditorDictation } from '../../codeEditor/browser/dictation/editorDictation.js';16import { ContextMenuController } from '../../../../editor/contrib/contextmenu/browser/contextmenu.js';17import { SuggestController } from '../../../../editor/contrib/suggest/browser/suggestController.js';18import { SnippetController2 } from '../../../../editor/contrib/snippet/browser/snippetController2.js';19import { TabCompletionController } from '../../snippets/browser/tabCompletion.js';20import { IThemeService } from '../../../../platform/theme/common/themeService.js';21import { INotificationService } from '../../../../platform/notification/common/notification.js';22import { IAccessibilityService } from '../../../../platform/accessibility/common/accessibility.js';23import { ICommentThreadWidget } from '../common/commentThreadWidget.js';24import { CommentContextKeys } from '../common/commentContextKeys.js';25import { ILanguageConfigurationService } from '../../../../editor/common/languages/languageConfigurationRegistry.js';26import { ILanguageFeaturesService } from '../../../../editor/common/services/languageFeatures.js';27import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';28import { ICodeEditor } from '../../../../editor/browser/editorBrowser.js';29import { clamp } from '../../../../base/common/numbers.js';30import { CopyPasteController } from '../../../../editor/contrib/dropOrPasteInto/browser/copyPasteController.js';31import { CodeActionController } from '../../../../editor/contrib/codeAction/browser/codeActionController.js';32import { DropIntoEditorController } from '../../../../editor/contrib/dropOrPasteInto/browser/dropIntoEditorController.js';33import { InlineCompletionsController } from '../../../../editor/contrib/inlineCompletions/browser/controller/inlineCompletionsController.js';34import { LinkDetector } from '../../../../editor/contrib/links/browser/links.js';35import { MessageController } from '../../../../editor/contrib/message/browser/messageController.js';36import { SelectionClipboardContributionID } from '../../codeEditor/browser/selectionClipboard.js';37import { MenuId } from '../../../../platform/actions/common/actions.js';38import { ContentHoverController } from '../../../../editor/contrib/hover/browser/contentHoverController.js';39import { GlyphHoverController } from '../../../../editor/contrib/hover/browser/glyphHoverController.js';40import { PlaceholderTextContribution } from '../../../../editor/contrib/placeholderText/browser/placeholderTextContribution.js';4142export const ctxCommentEditorFocused = new RawContextKey<boolean>('commentEditorFocused', false);43export const MIN_EDITOR_HEIGHT = 5 * 18;44export const MAX_EDITOR_HEIGHT = 25 * 18;4546export interface LayoutableEditor {47getLayoutInfo(): { height: number };48}4950export class SimpleCommentEditor extends CodeEditorWidget {51private _parentThread: ICommentThreadWidget;52private _commentEditorFocused: IContextKey<boolean>;53private _commentEditorEmpty: IContextKey<boolean>;5455constructor(56domElement: HTMLElement,57options: IEditorOptions,58scopedContextKeyService: IContextKeyService,59parentThread: ICommentThreadWidget,60@IInstantiationService instantiationService: IInstantiationService,61@ICodeEditorService codeEditorService: ICodeEditorService,62@ICommandService commandService: ICommandService,63@IThemeService themeService: IThemeService,64@INotificationService notificationService: INotificationService,65@IAccessibilityService accessibilityService: IAccessibilityService,66@ILanguageConfigurationService languageConfigurationService: ILanguageConfigurationService,67@ILanguageFeaturesService languageFeaturesService: ILanguageFeaturesService,68) {69const codeEditorWidgetOptions: ICodeEditorWidgetOptions = {70contributions: <IEditorContributionDescription[]>[71{ id: MenuPreventer.ID, ctor: MenuPreventer, instantiation: EditorContributionInstantiation.BeforeFirstInteraction },72{ id: ContextMenuController.ID, ctor: ContextMenuController, instantiation: EditorContributionInstantiation.BeforeFirstInteraction },73{ id: SuggestController.ID, ctor: SuggestController, instantiation: EditorContributionInstantiation.Eager },74{ id: SnippetController2.ID, ctor: SnippetController2, instantiation: EditorContributionInstantiation.Lazy },75{ id: TabCompletionController.ID, ctor: TabCompletionController, instantiation: EditorContributionInstantiation.Eager }, // eager because it needs to define a context key76{ id: EditorDictation.ID, ctor: EditorDictation, instantiation: EditorContributionInstantiation.Lazy },77...EditorExtensionsRegistry.getSomeEditorContributions([78CopyPasteController.ID,79DropIntoEditorController.ID,80LinkDetector.ID,81MessageController.ID,82ContentHoverController.ID,83GlyphHoverController.ID,84SelectionClipboardContributionID,85InlineCompletionsController.ID,86CodeActionController.ID,87PlaceholderTextContribution.ID88])89],90contextMenuId: MenuId.SimpleEditorContext91};9293super(domElement, options, codeEditorWidgetOptions, instantiationService, codeEditorService, commandService, scopedContextKeyService, themeService, notificationService, accessibilityService, languageConfigurationService, languageFeaturesService);9495this._commentEditorFocused = ctxCommentEditorFocused.bindTo(scopedContextKeyService);96this._commentEditorEmpty = CommentContextKeys.commentIsEmpty.bindTo(scopedContextKeyService);97this._commentEditorEmpty.set(!this.getModel()?.getValueLength());98this._parentThread = parentThread;99100this._register(this.onDidFocusEditorWidget(_ => this._commentEditorFocused.set(true)));101102this._register(this.onDidChangeModelContent(e => this._commentEditorEmpty.set(!this.getModel()?.getValueLength())));103this._register(this.onDidBlurEditorWidget(_ => this._commentEditorFocused.reset()));104}105106getParentThread(): ICommentThreadWidget {107return this._parentThread;108}109110protected _getActions(): Iterable<EditorAction> {111return EditorExtensionsRegistry.getEditorActions();112}113114public override updateOptions(newOptions: Readonly<IEditorOptions> | undefined): void {115const withLineNumberRemoved: Readonly<IEditorOptions> = { ...newOptions, lineNumbers: 'off' };116super.updateOptions(withLineNumberRemoved);117}118119public static getEditorOptions(configurationService: IConfigurationService): IEditorOptions {120return {121wordWrap: 'on',122glyphMargin: false,123lineNumbers: 'off',124folding: false,125selectOnLineNumbers: false,126scrollbar: {127vertical: 'visible',128verticalScrollbarSize: 14,129horizontal: 'auto',130useShadows: true,131verticalHasArrows: false,132horizontalHasArrows: false,133alwaysConsumeMouseWheel: false134},135overviewRulerLanes: 2,136lineDecorationsWidth: 0,137scrollBeyondLastLine: false,138renderLineHighlight: 'none',139fixedOverflowWidgets: true,140acceptSuggestionOnEnter: 'smart',141minimap: {142enabled: false143},144dropIntoEditor: { enabled: true },145autoClosingBrackets: configurationService.getValue('editor.autoClosingBrackets'),146quickSuggestions: false,147accessibilitySupport: configurationService.getValue<'auto' | 'off' | 'on'>('editor.accessibilitySupport'),148fontFamily: configurationService.getValue('editor.fontFamily'),149fontSize: configurationService.getValue('editor.fontSize'),150allowVariableLineHeights: false151};152}153}154155export function calculateEditorHeight(parentEditor: LayoutableEditor, editor: ICodeEditor, currentHeight: number): number {156const layoutInfo = editor.getLayoutInfo();157const lineHeight = editor.getOption(EditorOption.lineHeight);158const contentHeight = (editor._getViewModel()?.getLineCount()! * lineHeight); // Can't just call getContentHeight() because it returns an incorrect, large, value when the editor is first created.159if ((contentHeight > layoutInfo.height) ||160(contentHeight < layoutInfo.height && currentHeight > MIN_EDITOR_HEIGHT)) {161const linesToAdd = Math.ceil((contentHeight - layoutInfo.height) / lineHeight);162const proposedHeight = layoutInfo.height + (lineHeight * linesToAdd);163return clamp(proposedHeight, MIN_EDITOR_HEIGHT, clamp(parentEditor.getLayoutInfo().height - 90, MIN_EDITOR_HEIGHT, MAX_EDITOR_HEIGHT));164}165return currentHeight;166}167168169