Search code examples
ace-editor

Ace editor, inaccurate horizontal scroll, how to fix?


Using Ace editor, works OK, except: and start and end of line, if there is at least one line of the document that doesn't fit the screen, horizontal scroll is incomplete. For caret at start of line, once the view is h-scrolled, it won't scroll back fully when caret is at start of line, and thus the caret won't show. Annoying. And the same for caret at end of line (although it seems it doesn't scroll at all, rather than not flush right, so might be different bugs. Anybody know how to fix? And what versions are affected?

(Oh, right, forgot to mention: the gutter is enabled.)

(Edit II: using Google Chrome 18.0.1025.162)

(E#3: forgot to mention: using Shift+scroll wheel I can manually fix it, scrolling full left. (E4: ...and that's just a clue; not a solution. One should not have to do any extraneous manual mousing.))

(Edit#N: managed to hide the gutter: "editor_loaded.renderer.setShowGutter(false);". Problem persists.)


Solution

  • Well, as requested (by 'WarFox'), here's what I did to get around the scrolling issues in version 0.2.0, straight out of local repo. HTH, YMMV. No guarantees for modifying this or any version, of course. The code for this.scrollCursorIntoView is modified to be:

    this.scrollCursorIntoView = function() {
        var log = function (s) { 
            // console.log("### scrollCursorIntoView ###: " + s); 
        };
        // log("(scrollCursorIntoView...)");
        function loge(expr) {
            var value = eval(expr);
            log("" + expr + " => " + value);
        }
    
        // the editor is not visible
        if (this.$size.scrollerHeight === 0)
            return;
    
        var pos = this.$cursorLayer.getPixelPosition();
    
        var left = pos.left + this.$padding;
        log("left = " + left);
        var top = pos.top;
        log("top = " + top);
    
        if (this.scrollTop > top) {
            this.scrollToY(top);
        }
    
        if (this.scrollTop + this.$size.scrollerHeight < top + this.lineHeight) {
            this.scrollToY(top + this.lineHeight - this.$size.scrollerHeight);
        }
    
        var scrollLeft = this.scroller.scrollLeft;
    
        var left_ = left - this.characterWidth;
        log("(scrollLeft > left): " + scrollLeft + " > " + left);
        log("(scrollLeft > left_): " + scrollLeft + " > " + left_);
        if (scrollLeft > left_) {
            this.scrollToX(left_);
        } else {
            log("NOT (scrollLeft > left): " + scrollLeft + " > " + left);
            log("NOT (scrollLeft > left_): " + scrollLeft + " > " + left_);
        }
    
        loge("scrollLeft");
        log("scrollLeft = " + scrollLeft);
        log("this.$size.scrollerWidth = " + this.$size.scrollerWidth);
        log("left = " + left);
        log("this.characterWidth = " + this.characterWidth);
    
        var right_side_scroll_yes = scrollLeft + this.$size.scrollerWidth < left + this.characterWidth;
        if (right_side_scroll_yes) {
            log("(right side scroll...)");
            //loge("this.layerConfig.width");
            if (left > this.layerConfig.width) {
                log("right #1");
                log("this.layerConfig.width = " + this.layerConfig.width);
                this.$desiredScrollLeft = left + 2 * this.characterWidth;
                this.scrollToX(this.$desiredScrollLeft);
            } else {
                log("right #2");
                var tmp = Math.round(left + this.characterWidth - this.$size.scrollerWidth);
                loge("tmp");
                this.scrollToX(tmp);
            }
        } else {
            log("NOT (right_side_scroll_yes): " + scrollLeft + " > " + left);
        }
    };
    

    Obviously, the logging calls are not necessary for anything but debugging.