Skip to content

Commit 3c9903f

Browse files
authored
Merge pull request microsoft#161836 from microsoft/alexd/pr-159226
PR microsoft#159226
2 parents 8013a36 + 313203e commit 3c9903f

File tree

6 files changed

+39
-11
lines changed

6 files changed

+39
-11
lines changed

src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,12 @@ class Widget {
432432
}
433433
}
434434

435+
// Left-align widgets that should appear :before content
436+
if (this._affinity === PositionAffinity.LeftOfInjectedText &&
437+
this._viewRange.startColumn === 1) {
438+
firstLineMinLeft = 0;
439+
}
440+
435441
let lastLineMinLeft = Constants.MAX_SAFE_SMALL_INTEGER;//lastLine.Constants.MAX_SAFE_SMALL_INTEGER;
436442
for (const visibleRange of lastLine.ranges) {
437443
if (visibleRange.left < lastLineMinLeft) {

src/vs/editor/contrib/hover/browser/contentHover.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { ContentWidgetPositionPreference, IActiveCodeEditor, ICodeEditor, IConte
1313
import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions';
1414
import { Position } from 'vs/editor/common/core/position';
1515
import { Range } from 'vs/editor/common/core/range';
16-
import { IModelDecoration } from 'vs/editor/common/model';
16+
import { IModelDecoration, PositionAffinity } from 'vs/editor/common/model';
1717
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
1818
import { TokenizationRegistry } from 'vs/editor/common/languages';
1919
import { HoverOperation, HoverStartMode, IHoverComputer } from 'vs/editor/contrib/hover/browser/hoverOperation';
@@ -261,6 +261,9 @@ export class ContentHoverController extends Disposable {
261261
disposables.add(participant.renderHoverParts(context, hoverParts));
262262
}
263263
}
264+
265+
const isBeforeContent = messages.some(m => m.isBeforeContent);
266+
264267
if (statusBar.hasContent) {
265268
fragment.appendChild(statusBar.hoverElement);
266269
}
@@ -283,6 +286,7 @@ export class ContentHoverController extends Disposable {
283286
showAtRange,
284287
this._editor.getOption(EditorOption.hover).above,
285288
this._computer.shouldFocus,
289+
isBeforeContent,
286290
anchor.initialMousePosX,
287291
anchor.initialMousePosY,
288292
disposables
@@ -368,6 +372,7 @@ class ContentHoverVisibleData {
368372
public readonly showAtRange: Range,
369373
public readonly preferAbove: boolean,
370374
public readonly stoleFocus: boolean,
375+
public readonly isBeforeContent: boolean,
371376
public initialMousePosX: number | undefined,
372377
public initialMousePosY: number | undefined,
373378
public readonly disposables: DisposableStore
@@ -439,6 +444,10 @@ export class ContentHoverWidget extends Disposable implements IContentWidget {
439444
// Prefer rendering above if the suggest widget is visible
440445
preferAbove = true;
441446
}
447+
448+
// :before content can align left of the text content
449+
const affinity = this._visibleData.isBeforeContent ? PositionAffinity.LeftOfInjectedText : undefined;
450+
442451
return {
443452
position: this._visibleData.showAtPosition,
444453
range: this._visibleData.showAtRange,
@@ -447,6 +456,7 @@ export class ContentHoverWidget extends Disposable implements IContentWidget {
447456
? [ContentWidgetPositionPreference.ABOVE, ContentWidgetPositionPreference.BELOW]
448457
: [ContentWidgetPositionPreference.BELOW, ContentWidgetPositionPreference.ABOVE]
449458
),
459+
positionAffinity: affinity
450460
};
451461
}
452462

src/vs/editor/contrib/hover/browser/hoverTypes.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ export interface IHoverPart {
2626
* even in the case of multiple hover parts.
2727
*/
2828
readonly forceShowAtRange?: boolean;
29+
30+
/**
31+
* If true, the hover item should appear before content
32+
*/
33+
readonly isBeforeContent?: boolean;
2934
/**
3035
* Is this hover part still valid for this new anchor?
3136
*/

src/vs/editor/contrib/hover/browser/markdownHoverParticipant.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export class MarkdownHover implements IHoverPart {
3030
public readonly owner: IEditorHoverParticipant<MarkdownHover>,
3131
public readonly range: Range,
3232
public readonly contents: IMarkdownString[],
33+
public readonly isBeforeContent: boolean,
3334
public readonly ordinal: number
3435
) { }
3536

@@ -55,7 +56,7 @@ export class MarkdownHoverParticipant implements IEditorHoverParticipant<Markdow
5556
) { }
5657

5758
public createLoadingMessage(anchor: HoverAnchor): MarkdownHover | null {
58-
return new MarkdownHover(this, anchor.range, [new MarkdownString().appendText(nls.localize('modesContentHover.loading', "Loading..."))], 2000);
59+
return new MarkdownHover(this, anchor.range, [new MarkdownString().appendText(nls.localize('modesContentHover.loading', "Loading..."))], false, 2000);
5960
}
6061

6162
public computeSync(anchor: HoverAnchor, lineDecorations: IModelDecoration[]): MarkdownHover[] {
@@ -78,9 +79,11 @@ export class MarkdownHoverParticipant implements IEditorHoverParticipant<Markdow
7879
if (typeof maxTokenizationLineLength === 'number' && lineLength >= maxTokenizationLineLength) {
7980
result.push(new MarkdownHover(this, anchor.range, [{
8081
value: nls.localize('too many characters', "Tokenization is skipped for long lines for performance reasons. This can be configured via `editor.maxTokenizationLineLength`.")
81-
}], index++));
82+
}], false, index++));
8283
}
8384

85+
let isBeforeContent = false;
86+
8487
for (const d of lineDecorations) {
8588
const startColumn = (d.range.startLineNumber === lineNumber) ? d.range.startColumn : 1;
8689
const endColumn = (d.range.endLineNumber === lineNumber) ? d.range.endColumn : maxColumn;
@@ -90,8 +93,12 @@ export class MarkdownHoverParticipant implements IEditorHoverParticipant<Markdow
9093
continue;
9194
}
9295

96+
if (d.options.beforeContentClassName) {
97+
isBeforeContent = true;
98+
}
99+
93100
const range = new Range(anchor.range.startLineNumber, startColumn, anchor.range.startLineNumber, endColumn);
94-
result.push(new MarkdownHover(this, range, asArray(hoverMessage), index++));
101+
result.push(new MarkdownHover(this, range, asArray(hoverMessage), isBeforeContent, index++));
95102
}
96103

97104
return result;
@@ -113,7 +120,7 @@ export class MarkdownHoverParticipant implements IEditorHoverParticipant<Markdow
113120
.filter(item => !isEmptyMarkdownString(item.hover.contents))
114121
.map(item => {
115122
const rng = item.hover.range ? Range.lift(item.hover.range) : anchor.range;
116-
return new MarkdownHover(this, rng, item.hover.contents, item.ordinal);
123+
return new MarkdownHover(this, rng, item.hover.contents, false, item.ordinal);
117124
});
118125
}
119126

src/vs/editor/contrib/inlayHints/browser/inlayHintsHover.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,11 @@ export class InlayHintsHover extends MarkdownHoverParticipant implements IEditor
9292
itemTooltip = part.item.hint.tooltip;
9393
}
9494
if (itemTooltip) {
95-
executor.emitOne(new MarkdownHover(this, anchor.range, [itemTooltip], 0));
95+
executor.emitOne(new MarkdownHover(this, anchor.range, [itemTooltip], false, 0));
9696
}
9797
// (1.2) Inlay dbl-click gesture
9898
if (isNonEmptyArray(part.item.hint.textEdits)) {
99-
executor.emitOne(new MarkdownHover(this, anchor.range, [new MarkdownString().appendText(localize('hint.dbl', "Double click to insert"))], 10001));
99+
executor.emitOne(new MarkdownHover(this, anchor.range, [new MarkdownString().appendText(localize('hint.dbl', "Double click to insert"))], false, 10001));
100100
}
101101

102102
// (2) Inlay Label Part Tooltip
@@ -107,7 +107,7 @@ export class InlayHintsHover extends MarkdownHoverParticipant implements IEditor
107107
partTooltip = part.part.tooltip;
108108
}
109109
if (partTooltip) {
110-
executor.emitOne(new MarkdownHover(this, anchor.range, [partTooltip], 1));
110+
executor.emitOne(new MarkdownHover(this, anchor.range, [partTooltip], false, 1));
111111
}
112112

113113
// (2.2) Inlay Label Part Help Hover
@@ -130,7 +130,7 @@ export class InlayHintsHover extends MarkdownHoverParticipant implements IEditor
130130
linkHint = new MarkdownString(`[${localize('hint.cmd', "Execute Command")}](${asCommandLink(part.part.command)} "${part.part.command.title}") (${kb})`, { isTrusted: true });
131131
}
132132
if (linkHint) {
133-
executor.emitOne(new MarkdownHover(this, anchor.range, [linkHint], 10000));
133+
executor.emitOne(new MarkdownHover(this, anchor.range, [linkHint], false, 10000));
134134
}
135135
}
136136

@@ -156,7 +156,7 @@ export class InlayHintsHover extends MarkdownHoverParticipant implements IEditor
156156
}
157157
return getHover(this._languageFeaturesService.hoverProvider, model, new Position(range.startLineNumber, range.startColumn), token)
158158
.filter(item => !isEmptyMarkdownString(item.hover.contents))
159-
.map(item => new MarkdownHover(this, part.item.anchor.range, item.hover.contents, 2 + item.ordinal));
159+
.map(item => new MarkdownHover(this, part.item.anchor.range, item.hover.contents, false, 2 + item.ordinal));
160160
} finally {
161161
ref.dispose();
162162
}

src/vs/editor/contrib/unicodeHighlighter/browser/unicodeHighlighter.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ export class UnicodeHighlighterHoverParticipant implements IEditorHoverParticipa
483483
.appendMarkdown(reason)
484484
.appendText(' ')
485485
.appendLink(uri, adjustSettings);
486-
result.push(new MarkdownHover(this, d.range, [markdown], index++));
486+
result.push(new MarkdownHover(this, d.range, [markdown], false, index++));
487487
}
488488
return result;
489489
}

0 commit comments

Comments
 (0)