src/vs/editor/common/cursor/cursorMoveOperations.ts/MoveOperations/vertical
class MoveOperations:	public static vertical(config: CursorConfiguration, model: ICursorSimpleModel, lineNumber: number, column: number, leftoverVisibleColumns: number, newLineNumber: number, allowMoveOnEdgeLine: boolean, normalizationAffinity?: PositionAffinity): CursorPosition {
		const currentVisibleColumn = CursorColumns.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize) + leftoverVisibleColumns;
		const lineCount = model.getLineCount();
		const wasOnFirstPosition = (lineNumber === 1 && column === 1);
		const wasOnLastPosition = (lineNumber === lineCount && column === model.getLineMaxColumn(lineNumber));
		const wasAtEdgePosition = (newLineNumber < lineNumber ? wasOnFirstPosition : wasOnLastPosition);

		lineNumber = newLineNumber;
		if (lineNumber < 1) {
			lineNumber = 1;
			if (allowMoveOnEdgeLine) {
				column = model.getLineMinColumn(lineNumber);
			} else {
				column = Math.min(model.getLineMaxColumn(lineNumber), column);
			}
		} else if (lineNumber > lineCount) {
			lineNumber = lineCount;
			if (allowMoveOnEdgeLine) {
				column = model.getLineMaxColumn(lineNumber);
			} else {
				column = Math.min(model.getLineMaxColumn(lineNumber), column);
			}
		} else {
			column = config.columnFromVisibleColumn(model, lineNumber, currentVisibleColumn);
		}

		if (wasAtEdgePosition) {
			leftoverVisibleColumns = 0;
		} else {
			leftoverVisibleColumns = currentVisibleColumn - CursorColumns.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize);
		}

		if (normalizationAffinity !== undefined) {
			const position = new Position(lineNumber, column);
			const newPosition = model.normalizePosition(position, normalizationAffinity);
			leftoverVisibleColumns = leftoverVisibleColumns + (column - newPosition.column);
			lineNumber = newPosition.lineNumber;
			column = newPosition.column;
		}
		return new CursorPosition(lineNumber, column, leftoverVisibleColumns);
	}