Fixes #151235: Always render the hover on the line of the anchor even if the hover provider returns a larger hover range

This commit is contained in:
Alex Dima 2022-06-17 16:02:21 +02:00
parent a6c39bc1fc
commit 5ca287646d
No known key found for this signature in database
GPG key ID: 39563C1504FDD0C9
2 changed files with 40 additions and 5 deletions

View file

@ -9,7 +9,6 @@ import { coalesce } from 'vs/base/common/arrays';
import { CancellationToken } from 'vs/base/common/cancellation';
import { KeyCode } from 'vs/base/common/keyCodes';
import { Disposable, DisposableStore, toDisposable } from 'vs/base/common/lifecycle';
import { Constants } from 'vs/base/common/uint';
import { ContentWidgetPositionPreference, IActiveCodeEditor, ICodeEditor, IContentWidget, IContentWidgetPosition, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser';
import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions';
import { Position } from 'vs/editor/common/core/position';
@ -254,19 +253,28 @@ export class ContentHoverController extends Disposable {
});
public static computeHoverRanges(anchorRange: Range, messages: IHoverPart[]) {
let renderColumn = Constants.MAX_SAFE_SMALL_INTEGER;
// The anchor range is always on a single line
const anchorLineNumber = anchorRange.startLineNumber;
let renderStartColumn = anchorRange.startColumn;
let renderEndColumn = anchorRange.endColumn;
let highlightRange: Range = messages[0].range;
let forceShowAtRange: Range | null = null;
for (const msg of messages) {
renderColumn = Math.min(renderColumn, msg.range.startColumn);
highlightRange = Range.plusRange(highlightRange, msg.range);
if (msg.range.startLineNumber === anchorLineNumber && msg.range.endLineNumber === anchorLineNumber) {
// this message has a range that is completely sitting on the line of the anchor
renderStartColumn = Math.min(renderStartColumn, msg.range.startColumn);
renderEndColumn = Math.max(renderEndColumn, msg.range.endColumn);
}
if (msg.forceShowAtRange) {
forceShowAtRange = msg.range;
}
}
return {
showAtPosition: forceShowAtRange ? forceShowAtRange.getStartPosition() : new Position(anchorRange.startLineNumber, renderColumn),
showAtRange: forceShowAtRange ? forceShowAtRange : highlightRange,
showAtPosition: forceShowAtRange ? forceShowAtRange.getStartPosition() : new Position(anchorRange.startLineNumber, renderStartColumn),
showAtRange: forceShowAtRange ? forceShowAtRange : new Range(anchorLineNumber, renderStartColumn, anchorLineNumber, renderEndColumn),
highlightRange
};
}

View file

@ -0,0 +1,27 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { ContentHoverController } from 'vs/editor/contrib/hover/browser/contentHover';
import { Range } from 'vs/editor/common/core/range';
import { Position } from 'vs/editor/common/core/position';
import { IHoverPart } from 'vs/editor/contrib/hover/browser/hoverTypes';
suite('Content Hover', () => {
test('issue #151235: Gitlens hover shows up in the wrong place', () => {
const actual = ContentHoverController.computeHoverRanges(
new Range(5, 5, 5, 5),
[<IHoverPart>{ range: new Range(4, 1, 5, 6) }]
);
assert.deepStrictEqual(
actual,
{
showAtPosition: new Position(5, 5),
showAtRange: new Range(5, 5, 5, 5),
highlightRange: new Range(4, 1, 5, 6)
}
);
});
});