我目前有一个语言服务器,可为关键字、函数、表、列等提供 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()
。所有自动完成数据均由后端发送。
有什么解决方法可以解决这个问题吗?
您可以在组件卸载时尝试此操作,处置编辑器
this.editor.dispose()
我也遇到了类似的问题,即触发多个 api 调用以完成代码。
我意识到摩纳哥实例创建是错误的。然后我在会话存储中设置了第一个摩纳哥实例,并在创建新实例之前检查是否存在任何先前的实例。
在您的情况下,您可以尝试在返回新实例之前检查
MonacoLanguageClient
的实例是否存在。
if(!JSON.parse(sessionStorage.getItem('moncao_lang_client'))){
return new MonacoLanguageClient({........
希望有帮助。