monaco-languageclient icon indicating copy to clipboard operation
monaco-languageclient copied to clipboard

Completion from multiple editors

Open pplonski opened this issue 3 years ago • 4 comments

Is it possible to provide completion for code that is distributed in multiple editors? Treat code from multiple editors as one code base and display completion to the editor that is currently focused?

I would like to create Python Notebook with a monaco-editor used in the cells. I would like to have one completion for all cells in one Notebook. For example, if I declare the function in the first cell I would like to see that function as known in other cells. Right now, the auto-completion works inside the cell.

I've created an example repo with Electron+monaco+python-lsp-server https://github.com/pplonski/electron-monaco-python-lsp I had two monaco-editors there. In the second editor the func1() is underlined with message that func1 is undefined name. Is it possible to join the models for completion purposes? To see func1() as a known name?

image

The main code used to display two editors:


const Hello = () => {
  function createLanguageClient(connection: any) {
    return new MonacoLanguageClient({
      name: 'Monaco language client',
      clientOptions: {
        documentSelector: ['python'],
        errorHandler: {
          error: () => ErrorAction.Continue,
          closed: () => CloseAction.DoNotRestart,
        },
      },
      connectionProvider: {
        get: (errorHandler, closeHandler) => {
          return Promise.resolve(
            createConnection(connection, errorHandler, closeHandler)
          );
        },
      },
    });
  }

  useEffect(() => {

    monaco.languages.register({
      id: 'python',
      extensions: ['.py'],
      aliases: ['python'],
      mimetypes: ['application/text'],
    });

    monaco.editor.create(document.getElementById('container')!, {
      model: monaco.editor.createModel(
        ['import numpy', 'def func1():', '\tpass', '', 'func1()'].join('\n'),
        'python',
        monaco.Uri.parse('inmemory://model.py')
      ),
    });

    monaco.editor.create(document.getElementById('container2')!, {
      model: monaco.editor.createModel(
        'func1()',
        'python',
        monaco.Uri.parse('inmemory://model2.py')
      ),
    });

    // // install Monaco language client services
    MonacoServices.install(monaco as typeof monaco_core);

    // hardcoded socket URL
    const url = 'ws://localhost:8999/index.html/monacoServer';
    const webSocket = new WebSocket(url);

    // listen when the web socket is opened
    listen({
      webSocket,
      onConnection: (connection) => {
        // create and start the language client
        const languageClient = createLanguageClient(connection);
        const disposable = languageClient.start();
        connection.onClose(() => disposable.dispose());
      },
    });
  }, []);

  return (
    <div>
      <h1>
        electron-react-boilerplate + monaco-editor + monaco-languageclient +
        python-lsp-server
      </h1>

      <div style={{ border: 'solid 2px blue' }}>
        <div id="container" style={{ height: '300px' }} />
      </div>
      <div style={{ border: 'solid 2px green' }}>
        <div id="container2" style={{ height: '300px' }} />
      </div>
    </div>
  );
};

I've created a similar issue also in the monaco-editor repository https://github.com/microsoft/monaco-editor/issues/2792 - I'm not sure where does it better fit?

pplonski avatar Nov 24 '21 12:11 pplonski

It's not related at all to monaco-editor itself.

The lsp protocol supports it and this library as well.

I'm not familliar with python, but don't you need to import the first file from the second? also I don't think inmemory scheme works well with language servers.

CGNonofr avatar Nov 24 '21 12:11 CGNonofr

I would like to treat the code from both editors as one - without importing. This is how Python Notebook works, you have several editors and in each, you can write code and execute only that sample from a single editor.

There is the example of Python Notebook:

also I don't think inmemory scheme works well with language servers.

which scheme will work well? Are there any docs?

pplonski avatar Nov 24 '21 12:11 pplonski

which scheme will work well? Are there any docs?

file maybe? also the language server probably works best the the file present on the disk

I would like to treat the code from both editors as one - without importing

You can maybe achieve it by configuring your python language server. If not, I don't think there is anything you can do except some complicated hacks

CGNonofr avatar Nov 24 '21 12:11 CGNonofr

(Python Notebooks just got implemented in the LSP protocol itself)

CGNonofr avatar May 23 '22 12:05 CGNonofr

@pplonski I am closing the issue. If there are further questions please open a discussion: https://github.com/TypeFox/monaco-languageclient/discussions

Thank you

kaisalmen avatar Oct 19 '22 07:10 kaisalmen