diff --git a/src/vs/editor/common/controller/cursor.ts b/src/vs/editor/common/controller/cursor.ts index 04fc4e751d3..66b8e2e3ec5 100644 --- a/src/vs/editor/common/controller/cursor.ts +++ b/src/vs/editor/common/controller/cursor.ts @@ -1455,26 +1455,46 @@ export class Cursor extends EventEmitter { private _editorScroll(ctx: IMultipleCursorOperationContext): boolean { let editorScrollArg: editorCommon.EditorScrollArguments = ctx.eventData; - let value = editorScrollArg.value || 1; + editorScrollArg.value = editorScrollArg.value || 1; switch (editorScrollArg.to) { case editorCommon.EditorScrollDirection.Up: - value = -(value); case editorCommon.EditorScrollDirection.Down: - ctx.requestScrollDeltaLines = value * (editorCommon.EditorScrollByUnit.Page === editorScrollArg.by ? this.cursors.getAll()[0].getPageSize() : 1); + return this._scrollUpOrDown(editorScrollArg, ctx); + } + return true; + } + + private _scrollUpOrDown(editorScrollArg: editorCommon.EditorScrollArguments, ctx: IMultipleCursorOperationContext): boolean { + let up = editorScrollArg.to === editorCommon.EditorScrollDirection.Up; + let noOfLines = 1; + let cursor: OneCursor = this.cursors.getAll()[0]; + switch (editorScrollArg.by) { + case editorCommon.EditorScrollByUnit.WrappedLine: + noOfLines = editorScrollArg.value; + break; + case editorCommon.EditorScrollByUnit.Line: + noOfLines = (up ? cursor.getDeltaViewLinesToRevealModelLineBeforeViewPortTop(editorScrollArg.value) : cursor.getDeltaViewLinesToRevealModelLineAfteriewPortBottom(editorScrollArg.value)) || 1; + break; + case editorCommon.EditorScrollByUnit.Page: + noOfLines = cursor.getPageSize() * editorScrollArg.value; + break; + case editorCommon.EditorScrollByUnit.HalfPage: + noOfLines = Math.round(this.cursors.getAll()[0].getPageSize() / 2) * editorScrollArg.value; break; } + ctx.requestScrollDeltaLines = (up ? -1 : 1) * noOfLines; return true; } private _scrollUp(isPaged: boolean, ctx: IMultipleCursorOperationContext): boolean { ctx.eventData = { to: editorCommon.EditorScrollDirection.Up, value: 1 }; - ctx.eventData.by = isPaged ? editorCommon.EditorScrollByUnit.Page : editorCommon.EditorScrollByUnit.Line; + ctx.eventData.by = isPaged ? editorCommon.EditorScrollByUnit.Page : editorCommon.EditorScrollByUnit.WrappedLine; return this._editorScroll(ctx); } private _scrollDown(isPaged: boolean, ctx: IMultipleCursorOperationContext): boolean { ctx.eventData = { to: editorCommon.EditorScrollDirection.Down, value: 1 }; - ctx.eventData.by = isPaged ? editorCommon.EditorScrollByUnit.Page : editorCommon.EditorScrollByUnit.Line; + ctx.eventData.by = isPaged ? editorCommon.EditorScrollByUnit.Page : editorCommon.EditorScrollByUnit.WrappedLine; return this._editorScroll(ctx); } diff --git a/src/vs/editor/common/controller/oneCursor.ts b/src/vs/editor/common/controller/oneCursor.ts index c6038b29c21..9884e39c04f 100644 --- a/src/vs/editor/common/controller/oneCursor.ts +++ b/src/vs/editor/common/controller/oneCursor.ts @@ -518,6 +518,34 @@ export class OneCursor { } // -- model + public getDeltaViewLinesToRevealModelLineBeforeViewPortTop(noOfLinesBeforeTop: number): number { + let visibleModelRange = this.viewModelHelper.getCurrentVisibleModelRangeInViewPort(); + let visibleViewRange = this.viewModelHelper.getCurrentVisibleViewRangeInViewPort(); + let startColumn = this.model.getLineMinColumn(visibleModelRange.startLineNumber); + let startViewLineOfModelLine = this.viewModelHelper.convertModelPositionToViewPosition(visibleModelRange.startLineNumber, startColumn).lineNumber; + + // Reveal first line if it is partially visible + let revealLineNumber = (startViewLineOfModelLine !== visibleViewRange.startLineNumber ? visibleModelRange.startLineNumber : visibleModelRange.startLineNumber - 1) - (noOfLinesBeforeTop - 1); + revealLineNumber = revealLineNumber > 1 ? revealLineNumber : 1; + let revealLineEndColumn = this.model.getLineMinColumn(revealLineNumber); + let revealViewLineNumber = this.viewModelHelper.convertModelPositionToViewPosition(revealLineNumber, revealLineEndColumn).lineNumber; + + return visibleViewRange.startLineNumber - revealViewLineNumber; + } + public getDeltaViewLinesToRevealModelLineAfteriewPortBottom(noOfLinesAfterBottom: number): number { + let visibleModelRange = this.viewModelHelper.getCurrentVisibleModelRangeInViewPort(); + let visibleViewRange = this.viewModelHelper.getCurrentVisibleViewRangeInViewPort(); + let endColumn = this.model.getLineMaxColumn(visibleModelRange.endLineNumber); + let endViewLineOfModelLine = this.viewModelHelper.convertModelPositionToViewPosition(visibleModelRange.endLineNumber, endColumn).lineNumber; + + // Reveal last line if it is partially visible + let revealLineNumber = (endViewLineOfModelLine !== visibleViewRange.endLineNumber ? visibleModelRange.endLineNumber : visibleModelRange.endLineNumber + 1) + (noOfLinesAfterBottom - 1); + revealLineNumber = revealLineNumber < this.model.getLineCount() ? revealLineNumber : this.model.getLineCount(); + let revealLineEndColumn = this.model.getLineMaxColumn(revealLineNumber); + let revealViewLineNumber = this.viewModelHelper.convertModelPositionToViewPosition(revealLineNumber, revealLineEndColumn).lineNumber; + + return revealViewLineNumber - visibleViewRange.endLineNumber; + } public getLineFromViewPortTop(lineFromTop: number = 1): number { let visibleRange = this.viewModelHelper.getCurrentVisibleModelRangeInViewPort(); let startColumn = this.model.getLineMinColumn(visibleRange.startLineNumber); diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index af7fcb77898..4607e6a18f2 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -4290,7 +4290,9 @@ export const EditorScrollDirection = { */ export const EditorScrollByUnit = { Line: 'line', - Page: 'page' + WrappedLine: 'wrappedLine', + Page: 'page', + HalfPage: 'halfPage' }; /** @@ -4366,7 +4368,7 @@ export var CommandDescription = { \`\`\` 'by': Unit to move. Default is computed based on 'to' value. \`\`\` - 'line', 'page' + 'line', 'wrappedLine', page', 'halfPage' \`\`\` 'value': Number of units to move. Default is '1'. `, diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index d201fedd4d8..89537baff71 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -3228,7 +3228,9 @@ declare module monaco.editor { */ export const EditorScrollByUnit: { Line: string; + WrappedLine: string; Page: string; + HalfPage: string; }; /**