Search code examples
monaco-editor

How to override editor-services


I'm trying to have a custom way of implementing go-to-definition and that requires to override the editor-services, especially openEditor(), and findModel() methods, as far as I saw.

I tried following this comment:
https://github.com/microsoft/monaco-editor/issues/291#issuecomment-450706479 But couldn't run it in monaco's playground since there's no override for findModel.

I tried to add it to the playground so it would look like that:

monaco.languages.register({ id: 'mySpecialLanguage' });

monaco.languages.registerDefinitionProvider('mySpecialLanguage', {
    provideDefinition: function(model, position, cancellationToken) {
        return {
            uri: monaco.Uri.parse('http://a/different/file.txt'),
            range: new monaco.Range(3, 1, 3, 1)
        };
    }
});

var editorService = {
    openEditor: function() {
        alert(`open editor called!` + JSON.stringify(arguments));
    },
    resolveEditor: function() {
        alert(`resolve editor called!` + JSON.stringify(arguments));
    },
    findModel:function(editor, data) {
        alert(`resolve editor called!` + JSON.stringify(arguments));
    }
};

monaco.editor.create(document.getElementById("container"), {
    value: '\n\Go to definition on this text',
    language: 'mySpecialLanguage'
}, { editorService: editorService });

But that doesn't work either, as it doesn't run the findModel implementation here and logs in the console the error that the model doesn't exist.

So I was looking to see how does the third argument in monaco.editor.create() looks like and how it should behave. That third argument is (?Override: IEditorOverrideServices).

The monaco docs aren't helpful and the TypeScript definition of it is too vauge:

export interface IEditorOverrideServices {
    [index: string]: any;
}

So how should it really be used?


Solution

  • My solution at the end was:

    const editor = monaco.editor.create(document.getElementById("container")!, {
        model: monaco.editor.createModel(value, 'python', monaco.Uri.parse('file:///users/gilad/monaco-languageclient/example/lib/python3/main.py')),
        glyphMargin: true,
        lightbulb: {
            enabled: true
        },
    });
    
    
    const editorService = (editor as any)._codeEditorService;
    const openEditorBase = editorService.openCodeEditor.bind(editorService);
    if(openEditorBase){
    
    }
      
    editorService.openCodeEditor = async (input: any, source: any, sideBySide: any) => {
        debugger 
        const result = await openEditorBase(input, source);
        if (result === null) {
            const fullPath = input.resource.path
            const lineNumber = input.options.selection.startLineNumber
    
            alert("file is at " + fullPath + ":" + lineNumber )
        }
        return result; // always return the base result
    };