Monaco 编辑器:删除多个编辑器实例的完成提供程序中的重复项

问题描述 投票:0回答:2

我目前有一个语言服务器,可为关键字、函数、表、列等提供 SQL 自动完成功能...

语言服务器在后端运行,它根据客户端的请求提供自动完成功能。 在前端,我有一个带有以下组件的反应应用程序:

import React, { Component } from 'react';
import * as monaco from 'monaco-editor';
import { listen } from '@codingame/monaco-jsonrpc';
import {
    MonacoLanguageClient,
    MonacoServices,
    createConnection,
    MessageConnection,
} from "monaco-languageclient";
import ReconnectingWebSocket from "reconnecting-websocket";
import { URI } from 'vscode-uri';

const LANGUAGE_ID = 'sql';

let languageClient: MonacoLanguageClient;

class MonacoEditor extends Component {
    componentDidMount() {
        const {
            wordWrap,
            showLineNumbers,
            readOnly,
            id
        } = this.props;
        
        // creating the editor
        this.editor = monaco.editor.create(document.getElementById(id) as HTMLElement, {
            model: monaco.editor.createModel('', LANGUAGE_ID, monaco.Uri.parse(`inmemory://model${id}.sql`)),
            minimap: { enabled: false },
            glyphMargin: true,
            lightbulb: {
                enabled: true
            },
            language: LANGUAGE_ID,
            fontSize: 14,
            matchBrackets: 'always',
            wordWrap: wordWrap ? 'on' : 'off',
            lineNumbers: showLineNumbers ? 'on' : 'off',
            readOnly,
            scrollBeyondLastLine: false
        });

        // installing the language client
        MonacoServices.install(monaco);

        function createLanguageClient(
            connection: MessageConnection
        ): MonacoLanguageClient {
            return new MonacoLanguageClient({
                name: "SQL Language Server MonacoClient",
                clientOptions: {
                    documentSelector: ["sql"],
                    workspaceFolder: {
                        uri: URI.file('/opt/monaco_editor'),
                        name: 'workspace',
                        index: 0
                    }
                },
                connectionProvider: {
                    get: (errorHandler, closeHandler) => {
                        return Promise.resolve(
                            createConnection(connection, errorHandler, closeHandler)
                        );
                    },
                },
            });
        }

        function createWebSocket(url: string): ReconnectingWebSocket {
            const socketOptions = {
                maxReconnectionDelay: 10000,
                minReconnectionDelay: 1000,
                reconnectionDelayGrowFactor: 1.3,
                connectionTimeout: 10000,
                maxRetries: Infinity,
                debug: false,
            };
            return new ReconnectingWebSocket(url, [], socketOptions);
        }

        const URL = "ws://localhost:8080";
        const webSocket = createWebSocket(URL) as WebSocket;
        listen({
            webSocket,
            onConnection: (connection) => {
                languageClient = createLanguageClient(connection);
                const disposable = languageClient.start();
                connection.onClose(() => disposable.dispose());
            },
        });
    }

    render() {
        const { id } = this.props;
        return (
            <div>
                <h1 style={{textAlign: 'center'}}>SQL Syntax checking</h1>
                <div id={id} style={{height: '600px', width: '100%' }} />
            </div>);
    }
}

export default MonacoEditor;

我想要实现的是在同一页面上拥有多个编辑器实例。但是,当我尝试这样做时,我在完成建议中收到重复的关键字(见下文)。

我尝试做一些研究,但找不到任何适合我的情况的东西。 正如您从代码中看到的,我没有任何可以处理的

monaco.languages.registerCompletionItemProvider()
。所有自动完成数据均由后端发送。 有什么解决方法可以解决这个问题吗?

reactjs monaco-editor language-server-protocol
2个回答
0
投票

您可以在组件卸载时尝试此操作,处置编辑器

this.editor.dispose()

0
投票

我也遇到了类似的问题,即触发多个 api 调用以完成代码。

我意识到摩纳哥实例创建是错误的。然后我在会话存储中设置了第一个摩纳哥实例,并在创建新实例之前检查是否存在任何先前的实例。

在您的情况下,您可以尝试在返回新实例之前检查

MonacoLanguageClient
的实例是否存在。

if(!JSON.parse(sessionStorage.getItem('moncao_lang_client'))){
            return new MonacoLanguageClient({........

希望有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.