6
6
import * as dom from '../../../../base/browser/dom.js' ;
7
7
import { alert } from '../../../../base/browser/ui/aria/aria.js' ;
8
8
import { IAction } from '../../../../base/common/actions.js' ;
9
+ import { RunOnceScheduler } from '../../../../base/common/async.js' ;
9
10
import { Codicon } from '../../../../base/common/codicons.js' ;
10
11
import { Color } from '../../../../base/common/color.js' ;
11
- import { Emitter , Event } from '../../../../base/common/event.js' ;
12
+ import { Event } from '../../../../base/common/event.js' ;
12
13
import { stripIcons } from '../../../../base/common/iconLabels.js' ;
13
14
import { Iterable } from '../../../../base/common/iterator.js' ;
14
15
import { KeyCode , KeyMod } from '../../../../base/common/keyCodes.js' ;
15
16
import { Lazy } from '../../../../base/common/lazy.js' ;
16
17
import { Disposable } from '../../../../base/common/lifecycle.js' ;
17
18
import { derived , disposableObservableValue , observableValue } from '../../../../base/common/observable.js' ;
18
- import { count } from '../../../../base/common/strings.js' ;
19
19
import { URI } from '../../../../base/common/uri.js' ;
20
20
import { ICodeEditor , isCodeEditor } from '../../../../editor/browser/editorBrowser.js' ;
21
21
import { EditorAction2 } from '../../../../editor/browser/editorExtensions.js' ;
@@ -678,10 +678,8 @@ export class TestingOutputPeekController extends Disposable implements IEditorCo
678
678
679
679
680
680
class TestResultsPeek extends PeekViewWidget {
681
- private static lastHeightInLines ?: number ;
682
-
683
- private readonly visibilityChange = this . _disposables . add ( new Emitter < boolean > ( ) ) ;
684
681
public readonly current = observableValue < InspectSubject | undefined > ( 'testPeekCurrent' , undefined ) ;
682
+ private resizeOnNextContentHeightUpdate = false ;
685
683
private content ! : TestResultsViewContent ;
686
684
private scopedContextKeyService ! : IContextKeyService ;
687
685
private dimension ?: dom . Dimension ;
@@ -701,10 +699,22 @@ class TestResultsPeek extends PeekViewWidget {
701
699
super ( editor , { showFrame : true , frameWidth : 1 , showArrow : true , isResizeable : true , isAccessible : true , className : 'test-output-peek' } , instantiationService ) ;
702
700
703
701
this . _disposables . add ( themeService . onDidColorThemeChange ( this . applyTheme , this ) ) ;
704
- this . _disposables . add ( this . onDidClose ( ( ) => this . visibilityChange . fire ( false ) ) ) ;
705
702
peekViewService . addExclusiveWidget ( editor , this ) ;
706
703
}
707
704
705
+ protected override _getMaximumHeightInLines ( ) : number | undefined {
706
+ const defaultMaxHeight = super . _getMaximumHeightInLines ( ) ;
707
+ const contentHeight = this . content ?. contentHeight ;
708
+ if ( ! contentHeight ) { // undefined or 0
709
+ return defaultMaxHeight ;
710
+ }
711
+
712
+ const lineHeight = this . editor . getOption ( EditorOption . lineHeight ) ;
713
+ // 41 is experimentally determined to be the overhead of the peek view itself
714
+ // to avoid showing scrollbars by default in its content.
715
+ return Math . min ( defaultMaxHeight || Infinity , ( contentHeight + 41 ) / lineHeight ) ;
716
+ }
717
+
708
718
private applyTheme ( ) {
709
719
const theme = this . themeService . getColorTheme ( ) ;
710
720
const current = this . current . get ( ) ;
@@ -764,6 +774,27 @@ class TestResultsPeek extends PeekViewWidget {
764
774
765
775
protected override _fillBody ( containerElement : HTMLElement ) : void {
766
776
this . content . fillBody ( containerElement ) ;
777
+
778
+ // Resize on height updates for a short time to allow any heights made
779
+ // by editor contributions to come into effect before.
780
+ const contentHeightSettleTimer = this . _disposables . add ( new RunOnceScheduler ( ( ) => {
781
+ this . resizeOnNextContentHeightUpdate = false ;
782
+ } , 500 ) ) ;
783
+
784
+ this . _disposables . add ( this . content . onDidChangeContentHeight ( height => {
785
+ if ( ! this . resizeOnNextContentHeightUpdate || ! height ) {
786
+ return ;
787
+ }
788
+
789
+ const displayed = this . _getMaximumHeightInLines ( ) ;
790
+ if ( displayed ) {
791
+ this . _relayout ( Math . min ( displayed , this . getVisibleEditorLines ( ) / 2 ) ) ;
792
+ if ( ! contentHeightSettleTimer . isScheduled ( ) ) {
793
+ contentHeightSettleTimer . schedule ( ) ;
794
+ }
795
+ }
796
+ } ) ) ;
797
+
767
798
this . _disposables . add ( this . content . onDidRequestReveal ( sub => {
768
799
TestingOutputPeekController . get ( this . editor ) ?. show ( sub instanceof MessageSubject
769
800
? sub . messageUri
@@ -780,7 +811,6 @@ class TestResultsPeek extends PeekViewWidget {
780
811
return this . showInPlace ( subject ) ;
781
812
}
782
813
783
- const message = subject . message ;
784
814
const previous = this . current ;
785
815
const revealLocation = subject . revealLocation ?. range . getStartPosition ( ) ;
786
816
if ( ! revealLocation && ! previous ) {
@@ -792,13 +822,8 @@ class TestResultsPeek extends PeekViewWidget {
792
822
return this . showInPlace ( subject ) ;
793
823
}
794
824
795
- // If there is a stack we want to display, ensure the default size is large-ish
796
- const peekLines = TestResultsPeek . lastHeightInLines || Math . max (
797
- inspectSubjectHasStack ( subject ) ? Math . ceil ( this . getVisibleEditorLines ( ) / 2 ) : 0 ,
798
- hintMessagePeekHeight ( message )
799
- ) ;
800
-
801
- this . show ( revealLocation , peekLines ) ;
825
+ this . resizeOnNextContentHeightUpdate = true ;
826
+ this . show ( revealLocation , 10 ) ; // 10 is just a random number, we resize once content is available
802
827
this . editor . revealRangeNearTopIfOutsideViewport ( Range . fromPositions ( revealLocation ) , ScrollType . Smooth ) ;
803
828
804
829
return this . showInPlace ( subject ) ;
@@ -832,11 +857,6 @@ class TestResultsPeek extends PeekViewWidget {
832
857
await this . content . reveal ( { subject, preserveFocus : false } ) ;
833
858
}
834
859
835
- protected override _relayout ( newHeightInLines : number ) : void {
836
- super . _relayout ( newHeightInLines ) ;
837
- TestResultsPeek . lastHeightInLines = newHeightInLines ;
838
- }
839
-
840
860
/** @override */
841
861
protected override _doLayoutBody ( height : number , width : number ) {
842
862
super . _doLayoutBody ( height , width ) ;
@@ -919,23 +939,11 @@ export class TestResultsView extends ViewPane {
919
939
}
920
940
}
921
941
922
- const hintMessagePeekHeight = ( msg : ITestMessage ) => {
923
- const msgHeight = ITestMessage . isDiffable ( msg )
924
- ? Math . max ( hintPeekStrHeight ( msg . actual ) , hintPeekStrHeight ( msg . expected ) )
925
- : hintPeekStrHeight ( typeof msg . message === 'string' ? msg . message : msg . message . value ) ;
926
-
927
- // add 8ish lines for the size of the title and decorations in the peek.
928
- return msgHeight + 8 ;
929
- } ;
930
-
931
942
const firstLine = ( str : string ) => {
932
943
const index = str . indexOf ( '\n' ) ;
933
944
return index === - 1 ? str : str . slice ( 0 , index ) ;
934
945
} ;
935
946
936
-
937
- const hintPeekStrHeight = ( str : string ) => Math . min ( count ( str , '\n' ) , 24 ) ;
938
-
939
947
function getOuterEditorFromDiffEditor ( codeEditorService : ICodeEditorService ) : ICodeEditor | null {
940
948
const diffEditors = codeEditorService . listDiffEditors ( ) ;
941
949
0 commit comments