From 66562856c8c7e60815da4fb166133d3c77dce9fc Mon Sep 17 00:00:00 2001 From: Joe Cheng Date: Tue, 15 Feb 2011 11:35:47 +0800 Subject: [PATCH] Fix PageUp/PageDown commands, which were badly broken on soft-wrapped documents --- lib/ace/editor.js | 56 +++++++++++++++++++------------------ lib/ace/selection.js | 9 ++++++ lib/ace/virtual_renderer.js | 4 +++ 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 60a14c1b..0e16b53a 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -805,68 +805,66 @@ var Editor =function(renderer, session) { return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow()); }; - this.getVisibleRowCount = function() { - return this.getLastVisibleRow() - this.getFirstVisibleRow() + 1; + this.$getVisibleRowCount = function() { + return this.renderer.getScrollBottomRow() - this.renderer.getScrollTopRow() + 1; }; - this.getPageDownRow = function() { - return this.renderer.getLastVisibleRow() - 1; + this.$getPageDownRow = function() { + return this.renderer.getScrollBottomRow(); }; - this.getPageUpRow = function() { - var firstRow = this.renderer.getFirstVisibleRow(); - var lastRow = this.renderer.getLastVisibleRow(); + this.$getPageUpRow = function() { + var firstRow = this.renderer.getScrollTopRow(); + var lastRow = this.renderer.getScrollBottomRow(); - return firstRow - (lastRow - firstRow) + 1; + return firstRow - (lastRow - firstRow); }; this.selectPageDown = function() { - var row = this.getPageDownRow() + Math.floor(this.getVisibleRowCount() / 2); + var row = this.$getPageDownRow() + Math.floor(this.$getVisibleRowCount() / 2); this.scrollPageDown(); var selection = this.getSelection(); - selection.$moveSelection(function() { - selection.moveCursorTo(row, selection.getSelectionLead().column); - }); + var leadScreenPos = this.session.documentToScreenPosition(selection.getSelectionLead()); + var dest = this.session.screenToDocumentPosition(row, leadScreenPos.column); + selection.selectTo(dest.row, dest.column); }; this.selectPageUp = function() { - var visibleRows = this.getLastVisibleRow() - this.getFirstVisibleRow(); - var row = this.getPageUpRow() + Math.round(visibleRows / 2); + var visibleRows = this.renderer.getScrollTopRow() - this.renderer.getScrollBottomRow(); + var row = this.$getPageUpRow() + Math.round(visibleRows / 2); this.scrollPageUp(); var selection = this.getSelection(); - selection.$moveSelection(function() { - selection.moveCursorTo(row, selection.getSelectionLead().column); - }); + var leadScreenPos = this.session.documentToScreenPosition(selection.getSelectionLead()); + var dest = this.session.screenToDocumentPosition(row, leadScreenPos.column); + selection.selectTo(dest.row, dest.column); }; this.gotoPageDown = function() { - var row = this.getPageDownRow(), - column = Math.min(this.getCursorPosition().column, - this.session.getLine(row).length); + var row = this.$getPageDownRow(); + var column = this.getCursorPositionScreen().column; this.scrollToRow(row); - this.getSelection().moveCursorTo(row, column); + this.getSelection().moveCursorToScreen(row, column); }; this.gotoPageUp = function() { - var row = this.getPageUpRow(), - column = Math.min(this.getCursorPosition().column, - this.session.getLine(row).length); + var row = this.$getPageUpRow(); + var column = this.getCursorPositionScreen().column; this.scrollToRow(row); - this.getSelection().moveCursorTo(row, column); + this.getSelection().moveCursorToScreen(row, column); }; this.scrollPageDown = function() { - this.scrollToRow(this.getPageDownRow()); + this.scrollToRow(this.$getPageDownRow()); }; this.scrollPageUp = function() { - this.renderer.scrollToRow(this.getPageUpRow()); + this.renderer.scrollToRow(this.$getPageUpRow()); }; this.scrollToRow = function(row) { @@ -887,6 +885,10 @@ var Editor =function(renderer, session) { return this.selection.getCursor(); }; + this.getCursorPositionScreen = function() { + return this.session.documentToScreenPosition(this.getCursorPosition()); + } + this.getSelectionRange = function() { return this.selection.getRange(); }; diff --git a/lib/ace/selection.js b/lib/ace/selection.js index a130228d..408f044a 100644 --- a/lib/ace/selection.js +++ b/lib/ace/selection.js @@ -408,6 +408,15 @@ var Selection = function(session) { this.$updateDesiredColumn(this.selectionLead.column); }; + this.moveCursorToScreen = function(row, column, preventUpdateDesiredColumn) { + if (this.session.getUseWrapMode()) { + var pos = this.session.screenToDocumentPosition(row, column); + row = pos.row; + column = pos.column; + } + this.moveCursorTo(row, column, preventUpdateDesiredColumn); + }; + }).call(Selection.prototype); exports.Selection = Selection; diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index 573aaf58..6be72b88 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -597,6 +597,10 @@ var VirtualRenderer = function(container, theme) { return this.scrollTop / this.lineHeight; }; + this.getScrollBottomRow = function() { + return Math.max(0, Math.floor((this.scrollTop + this.$size.scrollerHeight) / this.lineHeight) - 1); + } + this.scrollToRow = function(row) { this.scrollToY(row * this.lineHeight); };