I need to show a complete model in the editor without vertical scrolling. I can achieve it by listening to content changes of a model and calling layout with a recomputed height as lineCount * lineHeight. I wonder is the more elegant way to achieve it?
you can editor.getScrollHeight(), then set the height of the container (used in the create call) and then editor.layout();
At this point, that is the only way. Would be nice to have an autoSize: true|false flag that would do that for you
I noticed the following issues with auto resizing, disabled scrolling and scrollBeyondLastLine as false:
@akosyakov I'm thinking the mouse hits the horizontal scrollbar. Would you expect the content to have an extra 7px or the height of the horizontal scrollbar to avoid this?
@alexandrudima will try now
@alexandrudima you are right, i've adjusted the formula to add horizontalScrollbarHeight and it looks better. I would expect that it happens automatically if autoSize set to true.
also it would be nice to provide minHeightInLines, so in spite of a content is empty, an editor height can be for example 1.5*lineHeight
Another issue: Page scrolling does not work with auto resize and disabled scrolling.
Steps to reproduce: disable scrolling try to scroll a page down when a mouse is over an editor.
Filed a separate issue for it: https://github.com/Microsoft/monaco-editor/issues/116
@akosyakov I got this working when I add content to the model however, when I delete lines, the container will never shrink. Were you able to work around that?
@jws305 Yes, it works. Could it be that you did not hook it up at right places? We do autoresize whenever an editor configuration, an editor model or a model value changed.
The code that computes a height is here: https://github.com/R-Brain/jupyterlab/blob/master/src/monaco/editor.ts#L470. You can ignore boxSizing.
@akosyakov Thanks! That works much better than what I had come up with:
this.$element.height(0);
this.editor.layout();
let height = this.editor.getScrollHeight();
this.$element.height(height + 7);
this.editor.layout();
@akosyakov That code doesn't seem to exist anymore.
Care to share the original code?
Tnx!
Cool, thanks!
I tried to accomplish the exact same thing, but I couldn't find the line height in the layoutinfo.
Never thought to check the editor interface.
Thanks!
Some additional comments:
I believe that the performant way is to calculate the height using @akosyakov's approach:
let lastResizedLineCount = 0;
model.onDidChangeContent(() => {
let lineCount = model.getLineCount();
// Do not invalidate layout if the line count hasn't changed, as this method
// will be called for every keypress and layouts are too expensive.
if (lineCount == lastResizedLineCount) {
return;
}
lastResizedLineCount = lineCount;
const configuration = editor.getConfiguration();
const lineHeight = configuration.lineHeight;
const contentHeight = lineHeight * lineCount;
const horizontalScrollbarHeight = configuration.layoutInfo.horizontalScrollbarHeight;
const height = contentHeight + horizontalScrollbarHeight;
editorElement.style.height = `${height}px`;
editor.layout({
height,
width: this.getElement().clientWidth,
});
});
But this doesn't work with line-wrapping because the line count is dependent on the length of individual lines.
For that, I believe you have to use the line count from the ViewModel:
const lineCount = editor._modelData.viewModel.getLineCount()
Would really like to know if there's a better way which doesn't use the private _modelData member.
Let's track in #794 , which even though is a younger issue, has more upvotes.
Most helpful comment
At this point, that is the only way. Would be nice to have an
autoSize: true|falseflag that would do that for you