Skip to content

Commit 45b5e43

Browse files
authored
Merge pull request #281210 from microsoft/copilot/fix-suggest-widget-placement
Add NORTH placement for suggest details when forceRenderingAbove is used
2 parents bbf2868 + 09cead6 commit 45b5e43

File tree

1 file changed

+25
-4
lines changed

1 file changed

+25
-4
lines changed

src/vs/editor/contrib/suggest/browser/suggestWidgetDetails.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -406,15 +406,25 @@ export class SuggestDetailsOverlay implements IOverlayWidget {
406406
})();
407407

408408
// SOUTH
409-
const southPacement: Placement = (function () {
409+
const southPlacement: Placement = (function () {
410410
const left = anchorBox.left;
411411
const top = -info.borderWidth + anchorBox.top + anchorBox.height;
412412
const maxSizeBottom = new dom.Dimension(anchorBox.width - info.borderHeight, bodyBox.height - anchorBox.top - anchorBox.height - info.verticalPadding);
413413
return { top, left, fit: maxSizeBottom.height - size.height, maxSizeBottom, maxSizeTop: maxSizeBottom, minSize: defaultMinSize.with(maxSizeBottom.width) };
414414
})();
415415

416+
// NORTH
417+
const northPlacement: Placement = (function () {
418+
const left = anchorBox.left;
419+
const maxSizeTop = new dom.Dimension(anchorBox.width - info.borderHeight, anchorBox.top - info.verticalPadding);
420+
const top = Math.max(info.verticalPadding, anchorBox.top - size.height);
421+
return { top, left, fit: maxSizeTop.height - size.height, maxSizeTop, maxSizeBottom: maxSizeTop, minSize: defaultMinSize.with(maxSizeTop.width) };
422+
})();
423+
416424
// take first placement that fits or the first with "least bad" fit
417-
const placements = [eastPlacement, westPlacement, southPacement];
425+
// when the suggest widget is rendering above the cursor (preferAlignAtTop=false), prefer NORTH over SOUTH
426+
const verticalPlacement = preferAlignAtTop ? southPlacement : northPlacement;
427+
const placements = [eastPlacement, westPlacement, verticalPlacement];
418428
const placement = placements.find(p => p.fit >= 0) ?? placements.sort((a, b) => b.fit - a.fit)[0];
419429

420430
// top/bottom placement
@@ -445,7 +455,10 @@ export class SuggestDetailsOverlay implements IOverlayWidget {
445455
}
446456

447457
let { top, left } = placement;
448-
if (!alignAtTop && height > anchorBox.height) {
458+
if (placement === northPlacement) {
459+
// For NORTH placement, position the details above the anchor
460+
top = anchorBox.top - height + info.borderWidth;
461+
} else if (!alignAtTop && height > anchorBox.height) {
449462
top = bottom - height;
450463
}
451464
const editorDomNode = this._editor.getDomNode();
@@ -457,7 +470,15 @@ export class SuggestDetailsOverlay implements IOverlayWidget {
457470
}
458471
this._applyTopLeft({ left, top });
459472

460-
this._resizable.enableSashes(!alignAtTop, placement === eastPlacement, alignAtTop, placement !== eastPlacement);
473+
// enableSashes(north, east, south, west)
474+
// For NORTH placement: enable north sash (resize upward from top), disable south (can't resize into the anchor)
475+
// Also enable west sash for horizontal resizing, consistent with SOUTH placement
476+
// For SOUTH placement and EAST/WEST placements: use existing logic based on alignAtTop
477+
if (placement === northPlacement) {
478+
this._resizable.enableSashes(true, false, false, true);
479+
} else {
480+
this._resizable.enableSashes(!alignAtTop, placement === eastPlacement, alignAtTop, placement !== eastPlacement);
481+
}
461482

462483
this._resizable.minSize = placement.minSize;
463484
this._resizable.maxSize = maxSize;

0 commit comments

Comments
 (0)