Automatically adjust height to contents in Ace Cloud 9 editor

limitlessloop picture limitlessloop · Jul 20, 2012 · Viewed 39.8k times · Source

I'm trying to add the Ace editor to a page, but I don't know how to get the height to be set automatically based on the length of its contents.

Ideally it would work so when the content changes the height is recalculated, but I would be happy with the height just being set on page load.

For a JavaScript novice can someone help me figure out how I work out the length of the code, how many lines it spans, what the new height is and how I update the DOM to reflect this?

I found this suggestion in a Google group, but I don't really understand what it's doing and how I get it to adjust the height.

editor.getSession().getDocument().getLength() *
editor.renderer.lineHeight + editor.renderer.scrollBar.getWidth()

Answer

(UPDATE: I'm not working with this at the moment, but my answer may be out of date. To try and incorporate what others have provided, I'll echo their mention of the minLines and maxLines properties, e.g.

editor.setOptions({
    maxLines: Infinity
});

Apparently infinity is "not a very good idea, since it will disable virtual viewport even for very large documents." So picking a limit may be better.

For history's sake, the old answer was:


The post you cite is just operating on the assumption that it's a fixed width font whose character height you know, and that you know the number of lines in the document. Multiply that together you get a pixel count for how tall the content is. The suggestion is that every time a character is pressed or a cut/paste happens (which may add or remove lines), you use JavaScript to apply this concrete new size to the items in your DOM with CSS styles.

(They throw in the "width" of a scrollbar into a height calculation, and I honestly can't tell you if there's a rationale behind that or not. I'll let someone else figure that part out.)

Anyway...if you have soft wrap on, the number of rendered screen lines spanned may be more than the number of "actual" lines in the document. So it is better to use editor.getSession().getScreenLength() than editor.getSession().getDocument().getLength().

I put the editor (position: absolute) inside of a section (position: relative), and it's the only item living in that section. This code is seemingly working for me for now, I'll update it if I learn more...!

$(document).ready(function(){

    var heightUpdateFunction = function() {

        // http://stackoverflow.com/questions/11584061/
        var newHeight =
                  editor.getSession().getScreenLength()
                  * editor.renderer.lineHeight
                  + editor.renderer.scrollBar.getWidth();

        $('#editor').height(newHeight.toString() + "px");
        $('#editor-section').height(newHeight.toString() + "px");

        // This call is required for the editor to fix all of
        // its inner structure for adapting to a change in size
        editor.resize();
    };

    // Set initial size to match initial content
    heightUpdateFunction();

    // Whenever a change happens inside the ACE editor, update
    // the size again
    editor.getSession().on('change', heightUpdateFunction);
}