@@ -65,7 +65,7 @@ export class CommandTrackerAddon extends Disposable implements ICommandTracker,
65
65
this . _selectionStart = null ;
66
66
}
67
67
68
- scrollToPreviousCommand ( scrollPosition : ScrollPosition = ScrollPosition . Top , retainSelection : boolean = false ) : void {
68
+ scrollToPreviousCommand ( scrollPosition : ScrollPosition = ScrollPosition . Middle , retainSelection : boolean = false ) : void {
69
69
if ( ! this . _terminal ) {
70
70
return ;
71
71
}
@@ -74,9 +74,11 @@ export class CommandTrackerAddon extends Disposable implements ICommandTracker,
74
74
}
75
75
76
76
let markerIndex ;
77
- const currentLineY = Math . min ( this . _getLine ( this . _terminal , this . _currentMarker ) , this . _terminal . buffer . active . baseY ) ;
77
+ const currentLineY = typeof this . _currentMarker === 'object'
78
+ ? this . _getTargetScrollLine ( this . _terminal , this . _currentMarker , scrollPosition )
79
+ : Math . min ( this . _getLine ( this . _terminal , this . _currentMarker ) , this . _terminal . buffer . active . baseY ) ;
78
80
const viewportY = this . _terminal . buffer . active . viewportY ;
79
- if ( ! retainSelection && currentLineY !== viewportY ) {
81
+ if ( typeof this . _currentMarker === 'object' ? ! this . _isMarkerInViewport ( this . _terminal , this . _currentMarker ) : currentLineY !== viewportY ) {
80
82
// The user has scrolled, find the line based on the current scroll position. This only
81
83
// works when not retaining selection
82
84
const markersBelowViewport = this . _getCommandMarkers ( ) . filter ( e => e . line >= viewportY ) . length ;
@@ -104,7 +106,7 @@ export class CommandTrackerAddon extends Disposable implements ICommandTracker,
104
106
this . _scrollToMarker ( this . _currentMarker , scrollPosition ) ;
105
107
}
106
108
107
- scrollToNextCommand ( scrollPosition : ScrollPosition = ScrollPosition . Top , retainSelection : boolean = false ) : void {
109
+ scrollToNextCommand ( scrollPosition : ScrollPosition = ScrollPosition . Middle , retainSelection : boolean = false ) : void {
108
110
if ( ! this . _terminal ) {
109
111
return ;
110
112
}
@@ -113,9 +115,11 @@ export class CommandTrackerAddon extends Disposable implements ICommandTracker,
113
115
}
114
116
115
117
let markerIndex ;
116
- const currentLineY = Math . min ( this . _getLine ( this . _terminal , this . _currentMarker ) , this . _terminal . buffer . active . baseY ) ;
118
+ const currentLineY = typeof this . _currentMarker === 'object'
119
+ ? this . _getTargetScrollLine ( this . _terminal , this . _currentMarker , scrollPosition )
120
+ : Math . min ( this . _getLine ( this . _terminal , this . _currentMarker ) , this . _terminal . buffer . active . baseY ) ;
117
121
const viewportY = this . _terminal . buffer . active . viewportY ;
118
- if ( ! retainSelection && currentLineY !== viewportY ) {
122
+ if ( typeof this . _currentMarker === 'object' ? ! this . _isMarkerInViewport ( this . _terminal , this . _currentMarker ) : currentLineY !== viewportY ) {
119
123
// The user has scrolled, find the line based on the current scroll position. This only
120
124
// works when not retaining selection
121
125
const markersAboveViewport = this . _getCommandMarkers ( ) . filter ( e => e . line <= viewportY ) . length ;
@@ -147,11 +151,24 @@ export class CommandTrackerAddon extends Disposable implements ICommandTracker,
147
151
if ( ! this . _terminal ) {
148
152
return ;
149
153
}
150
- let line = marker . line ;
154
+ if ( ! this . _isMarkerInViewport ( this . _terminal , marker ) ) {
155
+ const line = this . _getTargetScrollLine ( this . _terminal , marker , position ) ;
156
+ this . _terminal . scrollToLine ( line ) ;
157
+ }
158
+ }
159
+
160
+ private _getTargetScrollLine ( terminal : Terminal , marker : IMarker , position : ScrollPosition ) {
161
+ // Middle is treated at 1/4 of the viewport's size because context below is almost always
162
+ // more important than context above in the terminal.
151
163
if ( position === ScrollPosition . Middle ) {
152
- line = Math . max ( line - Math . floor ( this . _terminal . rows / 2 ) , 0 ) ;
164
+ return Math . max ( marker . line - Math . floor ( terminal . rows / 4 ) , 0 ) ;
153
165
}
154
- this . _terminal . scrollToLine ( line ) ;
166
+ return marker . line ;
167
+ }
168
+
169
+ private _isMarkerInViewport ( terminal : Terminal , marker : IMarker ) {
170
+ const viewportY = terminal . buffer . active . viewportY ;
171
+ return marker . line >= viewportY && marker . line < viewportY + terminal . rows ;
155
172
}
156
173
157
174
selectToPreviousCommand ( ) : void {
@@ -232,7 +249,7 @@ export class CommandTrackerAddon extends Disposable implements ICommandTracker,
232
249
return marker . line ;
233
250
}
234
251
235
- scrollToPreviousLine ( xterm : Terminal , scrollPosition : ScrollPosition = ScrollPosition . Top , retainSelection : boolean = false ) : void {
252
+ scrollToPreviousLine ( xterm : Terminal , scrollPosition : ScrollPosition = ScrollPosition . Middle , retainSelection : boolean = false ) : void {
236
253
if ( ! retainSelection ) {
237
254
this . _selectionStart = null ;
238
255
}
@@ -255,7 +272,7 @@ export class CommandTrackerAddon extends Disposable implements ICommandTracker,
255
272
this . _scrollToMarker ( this . _currentMarker , scrollPosition ) ;
256
273
}
257
274
258
- scrollToNextLine ( xterm : Terminal , scrollPosition : ScrollPosition = ScrollPosition . Top , retainSelection : boolean = false ) : void {
275
+ scrollToNextLine ( xterm : Terminal , scrollPosition : ScrollPosition = ScrollPosition . Middle , retainSelection : boolean = false ) : void {
259
276
if ( ! retainSelection ) {
260
277
this . _selectionStart = null ;
261
278
}
0 commit comments