Uses editor option to control editor placeholder. (#214427)

* Uses editor option to control editor placeholder.

Signed-off-by: Henning Dieterichs <hdieterichs@microsoft.com>
This commit is contained in:
Henning Dieterichs 2024-06-06 18:09:59 +02:00 committed by GitHub
parent 15bdea120d
commit f82523eb08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 200 additions and 146 deletions

View file

@ -128,11 +128,11 @@
"--vscode-dropdown-listBackground",
"--vscode-editor-background",
"--vscode-editor-findMatchBackground",
"--vscode-editor-findMatchForeground",
"--vscode-editor-findMatchBorder",
"--vscode-editor-findMatchForeground",
"--vscode-editor-findMatchHighlightBackground",
"--vscode-editor-findMatchHighlightForeground",
"--vscode-editor-findMatchHighlightBorder",
"--vscode-editor-findMatchHighlightForeground",
"--vscode-editor-findRangeHighlightBackground",
"--vscode-editor-findRangeHighlightBorder",
"--vscode-editor-focusedStackFrameHighlightBackground",
@ -145,6 +145,7 @@
"--vscode-editor-lineHighlightBackground",
"--vscode-editor-lineHighlightBorder",
"--vscode-editor-linkedEditingBackground",
"--vscode-editor-placeholder-foreground",
"--vscode-editor-rangeHighlightBackground",
"--vscode-editor-rangeHighlightBorder",
"--vscode-editor-selectionBackground",
@ -490,12 +491,12 @@
"--vscode-panelSectionHeader-background",
"--vscode-panelSectionHeader-border",
"--vscode-panelSectionHeader-foreground",
"--vscode-panelTitle-activeBorder",
"--vscode-panelTitle-activeForeground",
"--vscode-panelTitle-inactiveForeground",
"--vscode-panelStickyScroll-background",
"--vscode-panelStickyScroll-border",
"--vscode-panelStickyScroll-shadow",
"--vscode-panelTitle-activeBorder",
"--vscode-panelTitle-activeForeground",
"--vscode-panelTitle-inactiveForeground",
"--vscode-peekView-border",
"--vscode-peekViewEditor-background",
"--vscode-peekViewEditor-matchHighlightBackground",
@ -519,6 +520,7 @@
"--vscode-problemsWarningIcon-foreground",
"--vscode-profileBadge-background",
"--vscode-profileBadge-foreground",
"--vscode-profiles-sashBorder",
"--vscode-progressBar-background",
"--vscode-quickInput-background",
"--vscode-quickInput-foreground",
@ -570,11 +572,11 @@
"--vscode-sideBarSectionHeader-background",
"--vscode-sideBarSectionHeader-border",
"--vscode-sideBarSectionHeader-foreground",
"--vscode-sideBarTitle-background",
"--vscode-sideBarTitle-foreground",
"--vscode-sideBarStickyScroll-background",
"--vscode-sideBarStickyScroll-border",
"--vscode-sideBarStickyScroll-shadow",
"--vscode-sideBarTitle-background",
"--vscode-sideBarTitle-foreground",
"--vscode-sideBySideEditor-horizontalBorder",
"--vscode-sideBySideEditor-verticalBorder",
"--vscode-simpleFindWidget-sashBorder",
@ -649,9 +651,6 @@
"--vscode-tab-activeBackground",
"--vscode-tab-activeBorder",
"--vscode-tab-activeBorderTop",
"--vscode-tab-selectedBorderTop",
"--vscode-tab-selectedBackground",
"--vscode-tab-selectedForeground",
"--vscode-tab-activeForeground",
"--vscode-tab-activeModifiedBorder",
"--vscode-tab-border",
@ -663,6 +662,9 @@
"--vscode-tab-inactiveForeground",
"--vscode-tab-inactiveModifiedBorder",
"--vscode-tab-lastPinnedBorder",
"--vscode-tab-selectedBackground",
"--vscode-tab-selectedBorderTop",
"--vscode-tab-selectedForeground",
"--vscode-tab-unfocusedActiveBackground",
"--vscode-tab-unfocusedActiveBorder",
"--vscode-tab-unfocusedActiveBorderTop",
@ -700,10 +702,10 @@
"--vscode-terminal-foreground",
"--vscode-terminal-hoverHighlightBackground",
"--vscode-terminal-inactiveSelectionBackground",
"--vscode-terminal-initialHintForeground",
"--vscode-terminal-selectionBackground",
"--vscode-terminal-selectionForeground",
"--vscode-terminal-tab-activeBorder",
"--vscode-terminal-initialHintForeground",
"--vscode-terminalCommandDecoration-defaultBackground",
"--vscode-terminalCommandDecoration-errorBackground",
"--vscode-terminalCommandDecoration-successBackground",
@ -853,4 +855,4 @@
"--zoom-factor",
"--test-bar-width"
]
}
}

View file

@ -8,7 +8,7 @@ import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecyc
import { IObservable, ITransaction, autorunOpts, autorunWithStoreHandleChanges, derived, derivedOpts, observableFromEvent, observableSignal, observableValue, observableValueOpts } from 'vs/base/common/observable';
import { TransactionImpl } from 'vs/base/common/observableInternal/base';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
import { EditorOption, FindComputedEditorOptionValueById } from 'vs/editor/common/config/editorOptions';
import { Position } from 'vs/editor/common/core/position';
import { Selection } from 'vs/editor/common/core/selection';
import { ICursorSelectionChangedEvent } from 'vs/editor/common/cursorEvents';
@ -174,6 +174,12 @@ export class ObservableCodeEditor extends Disposable {
public readonly onDidType = observableSignal<string>(this);
public getOption<T extends EditorOption>(id: T): IObservable<FindComputedEditorOptionValueById<T>> {
return observableFromEvent(cb => this.editor.onDidChangeConfiguration(e => {
if (e.hasChanged(id)) { cb(undefined); }
}), () => this.editor.getOption(id));
}
public setDecorations(decorations: IObservable<IModelDeltaDecoration[]>): IDisposable {
const d = new DisposableStore();
const decorationsCollection = this.editor.createDecorationsCollection();

View file

@ -692,6 +692,13 @@ export interface IEditorOptions {
* Defaults to false.
*/
peekWidgetDefaultFocus?: 'tree' | 'editor';
/**
* Sets a placeholder for the editor.
* If set, the placeholder is shown if the editor is empty.
*/
placeholder?: string | undefined;
/**
* Controls whether the definition link opens element in the peek widget.
* Defaults to false.
@ -3347,6 +3354,25 @@ class EditorPixelRatio extends ComputedEditorOption<EditorOption.pixelRatio, num
//#endregion
//#region
class PlaceholderOption extends BaseEditorOption<EditorOption.placeholder, string | undefined, string | undefined> {
constructor() {
super(EditorOption.placeholder, 'placeholder', undefined);
}
public validate(input: any): string | undefined {
if (typeof input === 'undefined') {
return this.defaultValue;
}
if (typeof input === 'string') {
return input;
}
return this.defaultValue;
}
}
//#endregion
//#region quickSuggestions
export type QuickSuggestionsValue = 'on' | 'inline' | 'off';
@ -5354,6 +5380,7 @@ export const enum EditorOption {
pasteAs,
parameterHints,
peekWidgetDefaultFocus,
placeholder,
definitionLinkOpensInPeek,
quickSuggestions,
quickSuggestionsDelay,
@ -5884,6 +5911,7 @@ export const EditorOptions = {
description: nls.localize('peekWidgetDefaultFocus', "Controls whether to focus the inline editor or the tree in the peek widget.")
}
)),
placeholder: register(new PlaceholderOption()),
definitionLinkOpensInPeek: register(new EditorBooleanOption(
EditorOption.definitionLinkOpensInPeek, 'definitionLinkOpensInPeek', false,
{ description: nls.localize('definitionLinkOpensInPeek', "Controls whether the Go to Definition mouse gesture always opens the peek widget.") }

View file

@ -261,68 +261,69 @@ export enum EditorOption {
pasteAs = 85,
parameterHints = 86,
peekWidgetDefaultFocus = 87,
definitionLinkOpensInPeek = 88,
quickSuggestions = 89,
quickSuggestionsDelay = 90,
readOnly = 91,
readOnlyMessage = 92,
renameOnType = 93,
renderControlCharacters = 94,
renderFinalNewline = 95,
renderLineHighlight = 96,
renderLineHighlightOnlyWhenFocus = 97,
renderValidationDecorations = 98,
renderWhitespace = 99,
revealHorizontalRightPadding = 100,
roundedSelection = 101,
rulers = 102,
scrollbar = 103,
scrollBeyondLastColumn = 104,
scrollBeyondLastLine = 105,
scrollPredominantAxis = 106,
selectionClipboard = 107,
selectionHighlight = 108,
selectOnLineNumbers = 109,
showFoldingControls = 110,
showUnused = 111,
snippetSuggestions = 112,
smartSelect = 113,
smoothScrolling = 114,
stickyScroll = 115,
stickyTabStops = 116,
stopRenderingLineAfter = 117,
suggest = 118,
suggestFontSize = 119,
suggestLineHeight = 120,
suggestOnTriggerCharacters = 121,
suggestSelection = 122,
tabCompletion = 123,
tabIndex = 124,
unicodeHighlighting = 125,
unusualLineTerminators = 126,
useShadowDOM = 127,
useTabStops = 128,
wordBreak = 129,
wordSegmenterLocales = 130,
wordSeparators = 131,
wordWrap = 132,
wordWrapBreakAfterCharacters = 133,
wordWrapBreakBeforeCharacters = 134,
wordWrapColumn = 135,
wordWrapOverride1 = 136,
wordWrapOverride2 = 137,
wrappingIndent = 138,
wrappingStrategy = 139,
showDeprecated = 140,
inlayHints = 141,
editorClassName = 142,
pixelRatio = 143,
tabFocusMode = 144,
layoutInfo = 145,
wrappingInfo = 146,
defaultColorDecorators = 147,
colorDecoratorsActivatedOn = 148,
inlineCompletionsAccessibilityVerbose = 149
placeholder = 88,
definitionLinkOpensInPeek = 89,
quickSuggestions = 90,
quickSuggestionsDelay = 91,
readOnly = 92,
readOnlyMessage = 93,
renameOnType = 94,
renderControlCharacters = 95,
renderFinalNewline = 96,
renderLineHighlight = 97,
renderLineHighlightOnlyWhenFocus = 98,
renderValidationDecorations = 99,
renderWhitespace = 100,
revealHorizontalRightPadding = 101,
roundedSelection = 102,
rulers = 103,
scrollbar = 104,
scrollBeyondLastColumn = 105,
scrollBeyondLastLine = 106,
scrollPredominantAxis = 107,
selectionClipboard = 108,
selectionHighlight = 109,
selectOnLineNumbers = 110,
showFoldingControls = 111,
showUnused = 112,
snippetSuggestions = 113,
smartSelect = 114,
smoothScrolling = 115,
stickyScroll = 116,
stickyTabStops = 117,
stopRenderingLineAfter = 118,
suggest = 119,
suggestFontSize = 120,
suggestLineHeight = 121,
suggestOnTriggerCharacters = 122,
suggestSelection = 123,
tabCompletion = 124,
tabIndex = 125,
unicodeHighlighting = 126,
unusualLineTerminators = 127,
useShadowDOM = 128,
useTabStops = 129,
wordBreak = 130,
wordSegmenterLocales = 131,
wordSeparators = 132,
wordWrap = 133,
wordWrapBreakAfterCharacters = 134,
wordWrapBreakBeforeCharacters = 135,
wordWrapColumn = 136,
wordWrapOverride1 = 137,
wordWrapOverride2 = 138,
wrappingIndent = 139,
wrappingStrategy = 140,
showDeprecated = 141,
inlayHints = 142,
editorClassName = 143,
pixelRatio = 144,
tabFocusMode = 145,
layoutInfo = 146,
wrappingInfo = 147,
defaultColorDecorators = 148,
colorDecoratorsActivatedOn = 149,
inlineCompletionsAccessibilityVerbose = 150
}
/**

View file

@ -5,15 +5,22 @@
import { structuralEquals } from 'vs/base/common/equals';
import { Disposable } from 'vs/base/common/lifecycle';
import { derived, derivedOpts, observableValue } from 'vs/base/common/observable';
import { derived, derivedOpts } from 'vs/base/common/observable';
import 'vs/css!./placeholderText';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { EditorContributionInstantiation, registerEditorContribution } from 'vs/editor/browser/editorExtensions';
import { observableCodeEditor } from 'vs/editor/browser/observableUtilities';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
import { ghostTextForeground } from 'vs/editor/common/core/editorColorRegistry';
import { Range } from 'vs/editor/common/core/range';
import { IEditorContribution } from 'vs/editor/common/editorCommon';
import { IModelDeltaDecoration, InjectedTextCursorStops } from 'vs/editor/common/model';
import { localize } from 'vs/nls';
import { registerColor } from 'vs/platform/theme/common/colorUtils';
/**
* Use the editor option to set the placeholder text.
*/
export class PlaceholderTextContribution extends Disposable implements IEditorContribution {
public static get(editor: ICodeEditor): PlaceholderTextContribution {
return editor.getContribution<PlaceholderTextContribution>(PlaceholderTextContribution.ID)!;
@ -22,7 +29,7 @@ export class PlaceholderTextContribution extends Disposable implements IEditorCo
public static readonly ID = 'editor.contrib.placeholderText';
private readonly _editorObs = observableCodeEditor(this._editor);
private readonly _placeholderText = observableValue<string | undefined>(this, undefined);
private readonly _placeholderText = this._editorObs.getOption(EditorOption.placeholder);
private readonly _decorationOptions = derivedOpts<{ placeholder: string } | undefined>({ owner: this, equalsFn: structuralEquals }, reader => {
const p = this._placeholderText.read(reader);
@ -57,10 +64,8 @@ export class PlaceholderTextContribution extends Disposable implements IEditorCo
this._register(this._editorObs.setDecorations(this._decorations));
}
public setPlaceholderText(placeholder: string): void {
this._placeholderText.set(placeholder, undefined);
}
}
registerEditorContribution(PlaceholderTextContribution.ID, PlaceholderTextContribution, EditorContributionInstantiation.Lazy);
registerEditorContribution(PlaceholderTextContribution.ID, PlaceholderTextContribution, EditorContributionInstantiation.Eager);
registerColor('editor.placeholder.foreground', { dark: ghostTextForeground, light: ghostTextForeground, hcDark: ghostTextForeground, hcLight: ghostTextForeground }, localize('placeholderForeground', 'Foreground color of the placeholder text in the editor.'));

View file

@ -3,6 +3,10 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.monaco-editor .placeholder-text {
color: var(--vscode-editorGhostText-foreground) !important;
.monaco-editor {
--vscode-editor-placeholder-foreground: rgba(0, 0, 0, 0.5);
}
.monaco-editor .placeholder-text {
color: var(--vscode-editor-placeholder-foreground);
}

View file

@ -43,6 +43,7 @@ import 'vs/editor/contrib/longLinesHelper/browser/longLinesHelper';
import 'vs/editor/contrib/multicursor/browser/multicursor';
import 'vs/editor/contrib/inlineEdit/browser/inlineEdit.contribution';
import 'vs/editor/contrib/parameterHints/browser/parameterHints';
import 'vs/editor/contrib/placeholderText/browser/placeholderText.contribution';
import 'vs/editor/contrib/rename/browser/rename';
import 'vs/editor/contrib/sectionHeaders/browser/sectionHeaders';
import 'vs/editor/contrib/semanticTokens/browser/documentSemanticTokens';

131
src/vs/monaco.d.ts vendored
View file

@ -3735,6 +3735,11 @@ declare namespace monaco.editor {
* Defaults to false.
*/
peekWidgetDefaultFocus?: 'tree' | 'editor';
/**
* Sets a placeholder for the editor.
* If set, the placeholder is shown if the editor is empty.
*/
placeholder?: string | undefined;
/**
* Controls whether the definition link opens element in the peek widget.
* Defaults to false.
@ -4929,68 +4934,69 @@ declare namespace monaco.editor {
pasteAs = 85,
parameterHints = 86,
peekWidgetDefaultFocus = 87,
definitionLinkOpensInPeek = 88,
quickSuggestions = 89,
quickSuggestionsDelay = 90,
readOnly = 91,
readOnlyMessage = 92,
renameOnType = 93,
renderControlCharacters = 94,
renderFinalNewline = 95,
renderLineHighlight = 96,
renderLineHighlightOnlyWhenFocus = 97,
renderValidationDecorations = 98,
renderWhitespace = 99,
revealHorizontalRightPadding = 100,
roundedSelection = 101,
rulers = 102,
scrollbar = 103,
scrollBeyondLastColumn = 104,
scrollBeyondLastLine = 105,
scrollPredominantAxis = 106,
selectionClipboard = 107,
selectionHighlight = 108,
selectOnLineNumbers = 109,
showFoldingControls = 110,
showUnused = 111,
snippetSuggestions = 112,
smartSelect = 113,
smoothScrolling = 114,
stickyScroll = 115,
stickyTabStops = 116,
stopRenderingLineAfter = 117,
suggest = 118,
suggestFontSize = 119,
suggestLineHeight = 120,
suggestOnTriggerCharacters = 121,
suggestSelection = 122,
tabCompletion = 123,
tabIndex = 124,
unicodeHighlighting = 125,
unusualLineTerminators = 126,
useShadowDOM = 127,
useTabStops = 128,
wordBreak = 129,
wordSegmenterLocales = 130,
wordSeparators = 131,
wordWrap = 132,
wordWrapBreakAfterCharacters = 133,
wordWrapBreakBeforeCharacters = 134,
wordWrapColumn = 135,
wordWrapOverride1 = 136,
wordWrapOverride2 = 137,
wrappingIndent = 138,
wrappingStrategy = 139,
showDeprecated = 140,
inlayHints = 141,
editorClassName = 142,
pixelRatio = 143,
tabFocusMode = 144,
layoutInfo = 145,
wrappingInfo = 146,
defaultColorDecorators = 147,
colorDecoratorsActivatedOn = 148,
inlineCompletionsAccessibilityVerbose = 149
placeholder = 88,
definitionLinkOpensInPeek = 89,
quickSuggestions = 90,
quickSuggestionsDelay = 91,
readOnly = 92,
readOnlyMessage = 93,
renameOnType = 94,
renderControlCharacters = 95,
renderFinalNewline = 96,
renderLineHighlight = 97,
renderLineHighlightOnlyWhenFocus = 98,
renderValidationDecorations = 99,
renderWhitespace = 100,
revealHorizontalRightPadding = 101,
roundedSelection = 102,
rulers = 103,
scrollbar = 104,
scrollBeyondLastColumn = 105,
scrollBeyondLastLine = 106,
scrollPredominantAxis = 107,
selectionClipboard = 108,
selectionHighlight = 109,
selectOnLineNumbers = 110,
showFoldingControls = 111,
showUnused = 112,
snippetSuggestions = 113,
smartSelect = 114,
smoothScrolling = 115,
stickyScroll = 116,
stickyTabStops = 117,
stopRenderingLineAfter = 118,
suggest = 119,
suggestFontSize = 120,
suggestLineHeight = 121,
suggestOnTriggerCharacters = 122,
suggestSelection = 123,
tabCompletion = 124,
tabIndex = 125,
unicodeHighlighting = 126,
unusualLineTerminators = 127,
useShadowDOM = 128,
useTabStops = 129,
wordBreak = 130,
wordSegmenterLocales = 131,
wordSeparators = 132,
wordWrap = 133,
wordWrapBreakAfterCharacters = 134,
wordWrapBreakBeforeCharacters = 135,
wordWrapColumn = 136,
wordWrapOverride1 = 137,
wordWrapOverride2 = 138,
wrappingIndent = 139,
wrappingStrategy = 140,
showDeprecated = 141,
inlayHints = 142,
editorClassName = 143,
pixelRatio = 144,
tabFocusMode = 145,
layoutInfo = 146,
wrappingInfo = 147,
defaultColorDecorators = 148,
colorDecoratorsActivatedOn = 149,
inlineCompletionsAccessibilityVerbose = 150
}
export const EditorOptions: {
@ -5083,6 +5089,7 @@ declare namespace monaco.editor {
pasteAs: IEditorOption<EditorOption.pasteAs, Readonly<Required<IPasteAsOptions>>>;
parameterHints: IEditorOption<EditorOption.parameterHints, Readonly<Required<IEditorParameterHintOptions>>>;
peekWidgetDefaultFocus: IEditorOption<EditorOption.peekWidgetDefaultFocus, 'tree' | 'editor'>;
placeholder: IEditorOption<EditorOption.placeholder, string>;
definitionLinkOpensInPeek: IEditorOption<EditorOption.definitionLinkOpensInPeek, boolean>;
quickSuggestions: IEditorOption<EditorOption.quickSuggestions, InternalQuickSuggestionsOptions>;
quickSuggestionsDelay: IEditorOption<EditorOption.quickSuggestionsDelay, number>;