getValue ---> getOffsetAt stack overflow
monaco-editor version: 0.29.1 Browser: chrome OS: Playground code that reproduces the issue:
<template>
<div class="editor-container" :style="style">
<div @click="getValue">click me getalue</div>
<div ref="editorRef" class="editor" :style="style"> </div>
</div>
</template>
<script lang="ts">
import {
computed,
defineComponent,
nextTick,
onMounted,
reactive,
ref,
toRefs,
watch,
} from 'vue';
import * as monaco from 'monaco-editor';
import { editor } from 'monaco-editor';
export default defineComponent({
name: 'MonacoEditor1',
props: {
width: {
type: [String] as PropType<string>,
default: '100%' as string,
},
height: { type: [String, Number], default: '100%' },
},
setup(props) {
const state = reactive({
value: '',
});
const editorRef = ref();
const monacoEditor = ref<editor.IStandaloneCodeEditor | null>(null);
const style = computed(() => {
return {
width: !/^\d+$/.test(props.width) ? props.width : `${props.width}px`,
height: !/^\d+$/.test(String(props.height)) ? props.height : `${props.height}px`,
};
});
const creatMonacoEditor = () => {
monacoEditor.value = monaco.editor.create(editorRef.value, {
value: state.value,
language: 'sql',
});
monacoEditor.value.onDidChangeModelContent((e) => {
const value = monacoEditor.value.getValue();
});
};
const getValue = () => {
console.log('monacoEditor.value?.getValue', monacoEditor.value?.getValue());
}
watch(
() => style.value,
() => {
nextTick(() => {
if (monacoEditor.value) {
monacoEditor.value.layout();
}
});
},
);
onMounted(() => {
creatMonacoEditor();
});
return {
// data
...toRefs(state),
style,
getValue,
editorRef,
};
},
});
</script>
<style scoped>
.editor-container {
height: 100%;
}
</style>
this step
getOffsetAt(lineNumber, column) {
let leftLen = 0; // inorder
let x = this.root;
while (x !== SENTINEL) {
// here Infinite loop
if (x.left !== SENTINEL && x.lf_left + 1 >= lineNumber) {
x = x.left;
}
else if (x.lf_left + x.piece.lineFeedCnt + 1 >= lineNumber) {
leftLen += x.size_left;
// lineNumber >= 2
let accumualtedValInCurrentIndex = this.getAccumulatedValue(x, lineNumber - x.lf_left - 2);
return leftLen += accumualtedValInCurrentIndex + column - 1;
}
else {
lineNumber -= x.lf_left + x.piece.lineFeedCnt;
leftLen += x.size_left + x.piece.length;
x = x.right;
}
}
return leftLen;
}
i have the same question on vue3.x
I have solved this problem, here is my solution:
Don’t let your editor instance be a reactive variable, but as an ordinary variable
change
const monacoEditor = ref<editor.IStandaloneCodeEditor | null>(null);
to
const monacoEditor:editor.IStandaloneCodeEditor = null
@pyt111
monaco-editor version: 0.29.1 Browser: chrome OS: Playground code that reproduces the issue:
<template> <div class="editor-container" :style="style"> <div @click="getValue">click me getalue</div> <div ref="editorRef" class="editor" :style="style"> </div> </div> </template> <script lang="ts"> import { computed, defineComponent, nextTick, onMounted, reactive, ref, toRefs, watch, } from 'vue'; import * as monaco from 'monaco-editor'; import { editor } from 'monaco-editor'; export default defineComponent({ name: 'MonacoEditor1', props: { width: { type: [String] as PropType<string>, default: '100%' as string, }, height: { type: [String, Number], default: '100%' }, }, setup(props) { const state = reactive({ value: '', }); const editorRef = ref(); const monacoEditor = ref<editor.IStandaloneCodeEditor | null>(null); const style = computed(() => { return { width: !/^\d+$/.test(props.width) ? props.width : `${props.width}px`, height: !/^\d+$/.test(String(props.height)) ? props.height : `${props.height}px`, }; }); const creatMonacoEditor = () => { monacoEditor.value = monaco.editor.create(editorRef.value, { value: state.value, language: 'sql', }); monacoEditor.value.onDidChangeModelContent((e) => { const value = monacoEditor.value.getValue(); }); }; const getValue = () => { console.log('monacoEditor.value?.getValue', monacoEditor.value?.getValue()); } watch( () => style.value, () => { nextTick(() => { if (monacoEditor.value) { monacoEditor.value.layout(); } }); }, ); onMounted(() => { creatMonacoEditor(); }); return { // data ...toRefs(state), style, getValue, editorRef, }; }, }); </script> <style scoped> .editor-container { height: 100%; } </style>this step
getOffsetAt(lineNumber, column) { let leftLen = 0; // inorder let x = this.root; while (x !== SENTINEL) { // here Infinite loop if (x.left !== SENTINEL && x.lf_left + 1 >= lineNumber) { x = x.left; } else if (x.lf_left + x.piece.lineFeedCnt + 1 >= lineNumber) { leftLen += x.size_left; // lineNumber >= 2 let accumualtedValInCurrentIndex = this.getAccumulatedValue(x, lineNumber - x.lf_left - 2); return leftLen += accumualtedValInCurrentIndex + column - 1; } else { lineNumber -= x.lf_left + x.piece.lineFeedCnt; leftLen += x.size_left + x.piece.length; x = x.right; } } return leftLen; }
I have solved this problem, here is my solution:
Don’t let your editor instance be a reactive variable, but as an ordinary variable
change
const monacoEditor = ref<editor.IStandaloneCodeEditor | null>(null);to
const monacoEditor:editor.IStandaloneCodeEditor = null@pyt111
monaco-editor version: 0.29.1 Browser: chrome OS: Playground code that reproduces the issue:
<template> <div class="editor-container" :style="style"> <div @click="getValue">click me getalue</div> <div ref="editorRef" class="editor" :style="style"> </div> </div> </template> <script lang="ts"> import { computed, defineComponent, nextTick, onMounted, reactive, ref, toRefs, watch, } from 'vue'; import * as monaco from 'monaco-editor'; import { editor } from 'monaco-editor'; export default defineComponent({ name: 'MonacoEditor1', props: { width: { type: [String] as PropType<string>, default: '100%' as string, }, height: { type: [String, Number], default: '100%' }, }, setup(props) { const state = reactive({ value: '', }); const editorRef = ref(); const monacoEditor = ref<editor.IStandaloneCodeEditor | null>(null); const style = computed(() => { return { width: !/^\d+$/.test(props.width) ? props.width : `${props.width}px`, height: !/^\d+$/.test(String(props.height)) ? props.height : `${props.height}px`, }; }); const creatMonacoEditor = () => { monacoEditor.value = monaco.editor.create(editorRef.value, { value: state.value, language: 'sql', }); monacoEditor.value.onDidChangeModelContent((e) => { const value = monacoEditor.value.getValue(); }); }; const getValue = () => { console.log('monacoEditor.value?.getValue', monacoEditor.value?.getValue()); } watch( () => style.value, () => { nextTick(() => { if (monacoEditor.value) { monacoEditor.value.layout(); } }); }, ); onMounted(() => { creatMonacoEditor(); }); return { // data ...toRefs(state), style, getValue, editorRef, }; }, }); </script> <style scoped> .editor-container { height: 100%; } </style>this step
getOffsetAt(lineNumber, column) { let leftLen = 0; // inorder let x = this.root; while (x !== SENTINEL) { // here Infinite loop if (x.left !== SENTINEL && x.lf_left + 1 >= lineNumber) { x = x.left; } else if (x.lf_left + x.piece.lineFeedCnt + 1 >= lineNumber) { leftLen += x.size_left; // lineNumber >= 2 let accumualtedValInCurrentIndex = this.getAccumulatedValue(x, lineNumber - x.lf_left - 2); return leftLen += accumualtedValInCurrentIndex + column - 1; } else { lineNumber -= x.lf_left + x.piece.lineFeedCnt; leftLen += x.size_left + x.piece.length; x = x.right; } } return leftLen; }
you solved my problem, thank you very much
@Month7 I don't think that works for my use case, since the editor must be converted to a proxy to be shared between Vue blocks (e.g. between setup, mounted, and methods), or to be shared with other Vue components. However, I found a hack that seems to work, Object.freeze():
// Vue stuff
data(component) {
return {
editor: null as editor.IStandaloneCodeEditor | null,
};
},
mounted() {
const editor = monaco.editor.create(element, {});
this.editor = Object.freeze(editor);
console.log(this.editor.getValue()); // Prints correctly.
}
// More Vue stuff
Note: I ran into the same issue again, this time with context keys. Also fixed with freeze.
this.editor = Object.freeze(monaco.editor.create(element, {}));
this.contextKey = Object.freeze(this.editor.createContextKey('myContextKey', false));
this.contextKey.set(true);