diff --git a/lib/ace/Editor.js b/lib/ace/Editor.js index 0ef6d733..99c80d77 100644 --- a/lib/ace/Editor.js +++ b/lib/ace/Editor.js @@ -147,7 +147,11 @@ var Editor = function(renderer, doc) { this.setTheme = function(theme) { this.renderer.setTheme(theme); }; - + + this.setShowGutter = function(show){ + this.renderer.setShowGutter(show); + } + this.$highlightBrackets = function() { if (this.$bracketHighlight) { this.renderer.removeMarker(this.$bracketHighlight); @@ -688,18 +692,24 @@ var Editor = function(renderer, doc) { this.getLastVisibleRow = function() { return this.renderer.getLastVisibleRow(); }; + + this.getFirstFullyVisibleRow = function(){ + return this.renderer.getFirstFullyVisibleRow(); + } + + this.getLastFullyVisibleRow = function(){ + return this.renderer.getLastFullyVisibleRow(); + } this.isRowVisible = function(row) { - return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow()); + return (row >= this.getFirstFullyVisibleRow() && row <= this.getLastFullyVisibleRow()); }; this.getVisibleRowCount = function() { return this.getLastVisibleRow() - this.getFirstVisibleRow() + 1; }; - this.getPageDownRow = function() { - return this.renderer.getLastVisibleRow() - 1; - }; + this.getPageDownRow = this.getLastFullyVisibleRow; this.getPageUpRow = function() { var firstRow = this.renderer.getFirstVisibleRow(); @@ -790,11 +800,11 @@ var Editor = function(renderer, doc) { }; - this.gotoLine = function(lineNumber, row) { + this.gotoLine = function(lineNumber, column) { this.selection.clearSelection(); this.$blockScrolling = true; - this.moveCursorTo(lineNumber-1, row || 0); + this.moveCursorTo(lineNumber-1, column || 0); this.$blockScrolling = false; if (!this.isRowVisible(this.getCursorPosition().row)) { diff --git a/lib/ace/VirtualRenderer.js b/lib/ace/VirtualRenderer.js index 0075e2c2..6d0e16a4 100644 --- a/lib/ace/VirtualRenderer.js +++ b/lib/ace/VirtualRenderer.js @@ -92,6 +92,8 @@ var VirtualRenderer = function(container, theme) { (function() { + this.showGutter = true; + this.CHANGE_CURSOR = 1; this.CHANGE_MARKER = 2; this.CHANGE_GUTTER = 4; @@ -173,7 +175,7 @@ var VirtualRenderer = function(container, theme) { if (this.$size.width != width) { this.$size.width = width; - var gutterWidth = this.$gutter.offsetWidth; + var gutterWidth = this.showGutter ? this.$gutter.offsetWidth : 0; this.scroller.style.left = gutterWidth + "px"; this.scroller.style.width = Math.max(0, width - gutterWidth - this.scrollBar.getWidth()) + "px"; } @@ -228,6 +230,12 @@ var VirtualRenderer = function(container, theme) { this.getPrintMarginColumn = function() { return this.$printMarginColumn; }; + + this.setShowGutter = function(show){ + this.$gutter.style.display = show ? "block" : "none"; + this.showGutter = show; + this.onResize(); + } this.$updatePrintMargin = function() { if (!this.$showPrintMargin && !this.$printMarginEl) @@ -255,6 +263,21 @@ var VirtualRenderer = function(container, theme) { this.getFirstVisibleRow = function() { return (this.layerConfig || {}).firstRow || 0; }; + + this.getFirstFullyVisibleRow = function(){ + if (!this.layerConfig) + return 0; + + return this.layerConfig.firstRow + (this.layerConfig.offset == 0 ? 0 : 1); + } + + this.getLastFullyVisibleRow = function() { + if (!this.layerConfig) + return 0; + + var flint = Math.floor((this.layerConfig.height + this.layerConfig.offset) / this.layerConfig.lineHeight); + return this.layerConfig.firstRow - 1 + flint; + } this.getLastVisibleRow = function() { return (this.layerConfig || {}).lastRow || 0; @@ -286,7 +309,7 @@ var VirtualRenderer = function(container, theme) { // full if (changes & this.CHANGE_FULL) { this.$textLayer.update(this.layerConfig); - this.$gutterLayer.update(this.layerConfig); + this.showGutter && this.$gutterLayer.update(this.layerConfig); this.$markerLayer.update(this.layerConfig); this.$cursorLayer.update(this.layerConfig); this.$updateScrollBar(); @@ -297,13 +320,13 @@ var VirtualRenderer = function(container, theme) { if (changes & this.CHANGE_SCROLL) { if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES) { this.$textLayer.scrollLines(this.layerConfig); - this.$gutterLayer.update(this.layerConfig); + this.showGutter && this.$gutterLayer.update(this.layerConfig); this.$markerLayer.update(this.layerConfig); this.$cursorLayer.update(this.layerConfig); } else { this.$textLayer.update(this.layerConfig); - this.$gutterLayer.update(this.layerConfig); + this.showGutter && this.$gutterLayer.update(this.layerConfig); this.$markerLayer.update(this.layerConfig); this.$cursorLayer.update(this.layerConfig); } @@ -313,7 +336,7 @@ var VirtualRenderer = function(container, theme) { if (changes & this.CHANGE_TEXT) { this.$textLayer.update(this.layerConfig); - this.$gutterLayer.update(this.layerConfig); + this.showGutter && this.$gutterLayer.update(this.layerConfig); } else if (changes & this.CHANGE_LINES) { this.$updateLines(); @@ -321,9 +344,9 @@ var VirtualRenderer = function(container, theme) { } else if (changes & this.CHANGE_SCROLL) { this.$textLayer.scrollLines(this.layerConfig); - this.$gutterLayer.update(this.layerConfig); + this.showGutter && this.$gutterLayer.update(this.layerConfig); } if (changes & this.CHANGE_GUTTER) { - this.$gutterLayer.update(this.layerConfig); + this.showGutter && this.$gutterLayer.update(this.layerConfig); } if (changes & this.CHANGE_CURSOR) @@ -354,7 +377,9 @@ var VirtualRenderer = function(container, theme) { lastRow : lastRow, lineHeight : this.lineHeight, characterWidth : this.characterWidth, - minHeight : minHeight + minHeight : minHeight, + offset : offset, + height : this.$size.scrollerHeight }; for ( var i = 0; i < this.layers.length; i++) { @@ -389,7 +414,7 @@ var VirtualRenderer = function(container, theme) { // if the last row is unknown -> redraw everything if (lastRow === Infinity) { - this.$gutterLayer.update(layerConfig); + this.showGutter && this.$gutterLayer.update(layerConfig); this.$textLayer.update(layerConfig); return; } @@ -407,15 +432,26 @@ var VirtualRenderer = function(container, theme) { }; this.addMarker = function(range, clazz, type) { - return this.$markerLayer.addMarker(range, clazz, type); + var id = this.$markerLayer.addMarker(range, clazz, type); this.$loop.schedule(this.CHANGE_MARKER); + return id; }; this.removeMarker = function(markerId) { this.$markerLayer.removeMarker(markerId); this.$loop.schedule(this.CHANGE_MARKER); }; - + + this.addGutterDecoration = function(row, className){ + this.$gutterLayer.addGutterDecoration(row, className); + this.$loop.schedule(this.CHANGE_GUTTER); + } + + this.removeGutterDecoration = function(row, className){ + this.$gutterLayer.removeGutterDecoration(row, className); + this.$loop.schedule(this.CHANGE_GUTTER); + } + this.setBreakpoints = function(rows) { this.$gutterLayer.setBreakpoints(rows); this.$loop.schedule(this.CHANGE_GUTTER); diff --git a/lib/ace/layer/Gutter.js b/lib/ace/layer/Gutter.js index 373ad0a3..d3e8c3ea 100644 --- a/lib/ace/layer/Gutter.js +++ b/lib/ace/layer/Gutter.js @@ -13,15 +13,24 @@ var Gutter = function(parentEl) { parentEl.appendChild(this.element); this.$breakpoints = []; + this.$decorations = []; }; (function() { + this.addGutterDecoration = function(row, className){ + if (!this.$decorations[row]) + this.$decorations[row] = ""; + this.$decorations[row] += " ace_" + className; + } + + this.removeGutterDecoration = function(row, className){ + this.$decorations[row] = + this.$decorations[row].replace(" ace_" + className, ""); + } + this.setBreakpoints = function(rows) { this.$breakpoints = rows.concat(); - - if (this.$config) - this.update(this.$config); }; this.update = function(config) { @@ -30,6 +39,7 @@ var Gutter = function(parentEl) { var html = []; for ( var i = config.firstRow; i <= config.lastRow; i++) { html.push("