Skip to content

Commit

Permalink
Extends CodeEditorService so that rich decorations can be registered …
Browse files Browse the repository at this point in the history
…for injected text.

Adopts injected text for inlay text.
  • Loading branch information
hediet committed Jul 14, 2021
1 parent 9520f0a commit f1b3605
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 4 deletions.
25 changes: 22 additions & 3 deletions src/vs/editor/browser/services/codeEditorServiceImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { URI } from 'vs/base/common/uri';
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { AbstractCodeEditorService } from 'vs/editor/browser/services/abstractCodeEditorService';
import { IContentDecorationRenderOptions, IDecorationRenderOptions, IThemeDecorationRenderOptions, isThemeColor } from 'vs/editor/common/editorCommon';
import { IModelDecorationOptions, IModelDecorationOverviewRulerOptions, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model';
import { IModelDecorationOptions, IModelDecorationOverviewRulerOptions, InjectedTextOptions, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model';
import { IColorTheme, IThemeService, ThemeColor } from 'vs/platform/theme/common/themeService';

export class RefCountedStyleSheet {
Expand Down Expand Up @@ -250,6 +250,7 @@ export class DecorationTypeOptionsProvider implements IModelDecorationOptionsPro
public isWholeLine: boolean;
public overviewRuler: IModelDecorationOverviewRulerOptions | undefined;
public stickiness: TrackedRangeStickiness | undefined;
public beforeInjectedText: InjectedTextOptions | undefined;

constructor(description: string, themeService: IThemeService, styleSheet: GlobalStyleSheet | RefCountedStyleSheet, providerArgs: ProviderArguments) {
this.description = description;
Expand Down Expand Up @@ -283,6 +284,16 @@ export class DecorationTypeOptionsProvider implements IModelDecorationOptionsPro
}
this.beforeContentClassName = createCSSRules(ModelDecorationCSSRuleType.BeforeContentClassName);
this.afterContentClassName = createCSSRules(ModelDecorationCSSRuleType.AfterContentClassName);

if (providerArgs.options.beforeInjectedText && providerArgs.options.beforeInjectedText.contentText) {
const beforeInlineData = createInlineCSSRules(ModelDecorationCSSRuleType.BeforeInjectedTextClassName);
this.beforeInjectedText = {
content: providerArgs.options.beforeInjectedText.contentText,
inlineClassName: beforeInlineData?.className,
inlineClassNameAffectsLetterSpacing: beforeInlineData?.hasLetterSpacing || providerArgs.options.beforeInjectedText.affectsLetterSpacing
};
}

this.glyphMarginClassName = createCSSRules(ModelDecorationCSSRuleType.GlyphMarginClassName);

const options = providerArgs.options;
Expand All @@ -307,6 +318,7 @@ export class DecorationTypeOptionsProvider implements IModelDecorationOptionsPro
if (!writable) {
return this;
}

return {
description: this.description,
inlineClassName: this.inlineClassName,
Expand All @@ -316,7 +328,8 @@ export class DecorationTypeOptionsProvider implements IModelDecorationOptionsPro
glyphMarginClassName: this.glyphMarginClassName,
isWholeLine: this.isWholeLine,
overviewRuler: this.overviewRuler,
stickiness: this.stickiness
stickiness: this.stickiness,
before: this.beforeInjectedText
};
}

Expand Down Expand Up @@ -461,6 +474,11 @@ class DecorationCSSRules {
lightCSS = this.getCSSTextForModelDecorationContentClassName(options.light && options.light.after);
darkCSS = this.getCSSTextForModelDecorationContentClassName(options.dark && options.dark.after);
break;
case ModelDecorationCSSRuleType.BeforeInjectedTextClassName:
unthemedCSS = this.getCSSTextForModelDecorationContentClassName(options.beforeInjectedText);
lightCSS = this.getCSSTextForModelDecorationContentClassName(options.light && options.light.beforeInjectedText);
darkCSS = this.getCSSTextForModelDecorationContentClassName(options.dark && options.dark.beforeInjectedText);
break;
default:
throw new Error('Unknown rule type: ' + this._ruleType);
}
Expand Down Expand Up @@ -600,7 +618,8 @@ const enum ModelDecorationCSSRuleType {
InlineClassName = 1,
GlyphMarginClassName = 2,
BeforeContentClassName = 3,
AfterContentClassName = 4
AfterContentClassName = 4,
BeforeInjectedTextClassName = 5,
}

class CSSNameHelper {
Expand Down
2 changes: 2 additions & 0 deletions src/vs/editor/common/editorCommon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,8 @@ export interface IThemeDecorationRenderOptions {

before?: IContentDecorationRenderOptions;
after?: IContentDecorationRenderOptions;

beforeInjectedText?: IContentDecorationRenderOptions & { affectsLetterSpacing?: boolean };
}

/**
Expand Down
8 changes: 7 additions & 1 deletion src/vs/editor/contrib/inlayHints/inlayHintsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { IRange } from 'vs/base/common/range';
import { assertType } from 'vs/base/common/types';
import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { Position } from 'vs/editor/common/core/position';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';

const MAX_DECORATORS = 500;

Expand Down Expand Up @@ -65,6 +66,7 @@ export class InlayHintsController implements IEditorContribution {
private readonly _editor: ICodeEditor,
@ICodeEditorService private readonly _codeEditorService: ICodeEditorService,
@IThemeService private readonly _themeService: IThemeService,
@IContextKeyService private readonly _contextKeyService: IContextKeyService
) {
this._disposables.add(InlayHintsProviderRegistry.onDidChange(() => this._update()));
this._disposables.add(_themeService.onDidColorThemeChange(() => this._update()));
Expand Down Expand Up @@ -145,6 +147,9 @@ export class InlayHintsController implements IEditorContribution {
const fontFamilyVar = '--inlayHintsFontFamily';
this._editor.getContainerDomNode().style.setProperty(fontFamilyVar, fontFamily);

const key = this._contextKeyService.getContextKeyValue('config.editor.useInjectedText');
const shouldUseInjectedText = key === undefined ? true : !!key;

for (const { list: hints } of hintsData) {

for (let j = 0; j < hints.length && newDecorationsData.length < MAX_DECORATORS; j++) {
Expand All @@ -163,7 +168,8 @@ export class InlayHintsController implements IEditorContribution {
borderRadius: `${(fontSize / 4) | 0}px`,
};
const key = 'inlayHints-' + hash(before).toString(16);
this._codeEditorService.registerDecorationType('inlay-hints-controller', key, { before }, undefined, this._editor);
this._codeEditorService.registerDecorationType('inlay-hints-controller', key,
shouldUseInjectedText ? { beforeInjectedText: { ...before, affectsLetterSpacing: true } } : { before }, undefined, this._editor);

// decoration types are ref-counted which means we only need to
// call register und remove equally often

This comment has been minimized.

Copy link
@jogo-

jogo- Jul 14, 2021

Contributor

Typo: und -> and

This comment has been minimized.

Copy link
@hediet

hediet Jul 14, 2021

Author Member

Feel free to file a PR!

Expand Down

0 comments on commit f1b3605

Please sign in to comment.