diff --git a/src/vs/editor/common/viewModel.ts b/src/vs/editor/common/viewModel.ts index bedb93e902b..ff08d5fa24b 100644 --- a/src/vs/editor/common/viewModel.ts +++ b/src/vs/editor/common/viewModel.ts @@ -210,7 +210,11 @@ export interface ICoordinatesConverter { validateViewRange(viewRange: Range, expectedModelRange: Range): Range; // Model -> View conversion and related methods - convertModelPositionToViewPosition(modelPosition: Position, affinity?: PositionAffinity, allowZeroLineNumber?: boolean): Position; + /** + * @param allowZeroLineNumber Should it return 0 when there are hidden lines at the top and the position is in the hidden area? + * @param belowHiddenRanges When the model position is in a hidden area, should it return the first view position after or before? + */ + convertModelPositionToViewPosition(modelPosition: Position, affinity?: PositionAffinity, allowZeroLineNumber?: boolean, belowHiddenRanges?: boolean): Position; /** * @param affinity Only has an effect if the range is empty. */ diff --git a/src/vs/editor/common/viewModel/viewModelDecorations.ts b/src/vs/editor/common/viewModel/viewModelDecorations.ts index 239637ff916..4725c903073 100644 --- a/src/vs/editor/common/viewModel/viewModelDecorations.ts +++ b/src/vs/editor/common/viewModel/viewModelDecorations.ts @@ -82,7 +82,7 @@ export class ViewModelDecorations implements IDisposable { const options = modelDecoration.options; let viewRange: Range; if (options.isWholeLine) { - const start = this._coordinatesConverter.convertModelPositionToViewPosition(new Position(modelRange.startLineNumber, 1), PositionAffinity.Left); + const start = this._coordinatesConverter.convertModelPositionToViewPosition(new Position(modelRange.startLineNumber, 1), PositionAffinity.Left, false, true); const end = this._coordinatesConverter.convertModelPositionToViewPosition(new Position(modelRange.endLineNumber, this.model.getLineMaxColumn(modelRange.endLineNumber)), PositionAffinity.Right); viewRange = new Range(start.lineNumber, start.column, end.lineNumber, end.column); } else { diff --git a/src/vs/editor/common/viewModel/viewModelLines.ts b/src/vs/editor/common/viewModel/viewModelLines.ts index 487bbaa919e..c9fb7f3f662 100644 --- a/src/vs/editor/common/viewModel/viewModelLines.ts +++ b/src/vs/editor/common/viewModel/viewModelLines.ts @@ -830,16 +830,23 @@ export class ViewModelLinesFromProjectedModel implements IViewModelLines { return new Range(start.lineNumber, start.column, end.lineNumber, end.column); } - public convertModelPositionToViewPosition(_modelLineNumber: number, _modelColumn: number, affinity: PositionAffinity = PositionAffinity.None, allowZeroLineNumber: boolean = false): Position { + public convertModelPositionToViewPosition(_modelLineNumber: number, _modelColumn: number, affinity: PositionAffinity = PositionAffinity.None, allowZeroLineNumber: boolean = false, belowHiddenRanges: boolean = false): Position { const validPosition = this.model.validatePosition(new Position(_modelLineNumber, _modelColumn)); const inputLineNumber = validPosition.lineNumber; const inputColumn = validPosition.column; let lineIndex = inputLineNumber - 1, lineIndexChanged = false; - while (lineIndex > 0 && !this.modelLineProjections[lineIndex].isVisible()) { - lineIndex--; - lineIndexChanged = true; + if (belowHiddenRanges) { + while (lineIndex < this.modelLineProjections.length && !this.modelLineProjections[lineIndex].isVisible()) { + lineIndex++; + lineIndexChanged = true; + } + } else { + while (lineIndex > 0 && !this.modelLineProjections[lineIndex].isVisible()) { + lineIndex--; + lineIndexChanged = true; + } } if (lineIndex === 0 && !this.modelLineProjections[lineIndex].isVisible()) { // Could not reach a real line @@ -851,7 +858,11 @@ export class ViewModelLinesFromProjectedModel implements IViewModelLines { let r: Position; if (lineIndexChanged) { - r = this.modelLineProjections[lineIndex].getViewPositionOfModelPosition(deltaLineNumber, this.model.getLineMaxColumn(lineIndex + 1), affinity); + if (belowHiddenRanges) { + r = this.modelLineProjections[lineIndex].getViewPositionOfModelPosition(deltaLineNumber, 1, affinity); + } else { + r = this.modelLineProjections[lineIndex].getViewPositionOfModelPosition(deltaLineNumber, this.model.getLineMaxColumn(lineIndex + 1), affinity); + } } else { r = this.modelLineProjections[inputLineNumber - 1].getViewPositionOfModelPosition(deltaLineNumber, inputColumn, affinity); } @@ -1071,8 +1082,8 @@ class CoordinatesConverter implements ICoordinatesConverter { // Model -> View conversion and related methods - public convertModelPositionToViewPosition(modelPosition: Position, affinity?: PositionAffinity, allowZero?: boolean): Position { - return this._lines.convertModelPositionToViewPosition(modelPosition.lineNumber, modelPosition.column, affinity, allowZero); + public convertModelPositionToViewPosition(modelPosition: Position, affinity?: PositionAffinity, allowZero?: boolean, belowHiddenRanges?: boolean): Position { + return this._lines.convertModelPositionToViewPosition(modelPosition.lineNumber, modelPosition.column, affinity, allowZero, belowHiddenRanges); } public convertModelRangeToViewRange(modelRange: Range, affinity?: PositionAffinity): Range {