src/vs/workbench/contrib/terminal/browser/xterm/commandNavigationAddon.ts/CommandNavigationAddon/scrollToNextCommand
class CommandNavigationAddon:	scrollToNextCommand(scrollPosition: ScrollPosition = ScrollPosition.Middle, retainSelection: boolean = false): void {
		if (!this._terminal) {
			return;
		}
		if (!retainSelection) {
			this._selectionStart = null;
		}

		let markerIndex;
		const currentLineY = typeof this._currentMarker === 'object'
			? this._getTargetScrollLine(this._terminal, this._currentMarker, scrollPosition)
			: Math.min(this._getLine(this._terminal, this._currentMarker), this._terminal.buffer.active.baseY);
		const viewportY = this._terminal.buffer.active.viewportY;
		if (typeof this._currentMarker === 'object' ? !this._isMarkerInViewport(this._terminal, this._currentMarker) : currentLineY !== viewportY) {
			// The user has scrolled, find the line based on the current scroll position. This only
			// works when not retaining selection
			const markersAboveViewport = this._getCommandMarkers().filter(e => e.line <= viewportY).length;
			// markers.length will scroll to the bottom
			markerIndex = markersAboveViewport;
		} else if (this._currentMarker === Boundary.Bottom) {
			markerIndex = this._getCommandMarkers().length;
		} else if (this._currentMarker === Boundary.Top) {
			markerIndex = 0;
		} else if (this._isDisposable) {
			markerIndex = this._findNextCommand(this._terminal);
			this._currentMarker.dispose();
			this._isDisposable = false;
		} else {
			markerIndex = this._getCommandMarkers().indexOf(this._currentMarker) + 1;
		}

		if (markerIndex >= this._getCommandMarkers().length) {
			this._currentMarker = Boundary.Bottom;
			this._terminal.scrollToBottom();
			return;
		}

		this._currentMarker = this._getCommandMarkers()[markerIndex];
		this._scrollToMarker(this._currentMarker, scrollPosition);
	}