Add example of language server
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
NEXTAUTH_URL=https://example.com
|
||||
GITHUB_SECRET=""
|
||||
GITHUB_ID=""
|
||||
GITHUB_ID=""
|
||||
NEXT_PUBLIC_COMPILE_API_ENDPOINT="http://localhost:9000/api/build"
|
||||
NEXT_PUBLIC_LANGUAGE_SERVER_API_ENDPOINT="ws://localhost:9000/language-server/c"
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useRef } from "react";
|
||||
import { useSnapshot, ref } from "valtio";
|
||||
import Editor from "@monaco-editor/react";
|
||||
import Editor, { loader } from "@monaco-editor/react";
|
||||
import type monaco from "monaco-editor";
|
||||
import { ArrowBendLeftUp } from "phosphor-react";
|
||||
import { useTheme } from "next-themes";
|
||||
@@ -14,6 +14,15 @@ import { saveFile, state } from "../state";
|
||||
|
||||
import EditorNavigation from "./EditorNavigation";
|
||||
import Text from "./Text";
|
||||
import { MonacoServices } from "@codingame/monaco-languageclient";
|
||||
import { createLanguageClient, createWebSocket } from "../utils/languageClient";
|
||||
import { listen } from "@codingame/monaco-jsonrpc";
|
||||
|
||||
loader.config({
|
||||
paths: {
|
||||
vs: "https://cdn.jsdelivr.net/npm/monaco-editor@0.30.1/min/vs",
|
||||
},
|
||||
});
|
||||
|
||||
const HooksEditor = () => {
|
||||
const editorRef = useRef<monaco.editor.IStandaloneCodeEditor>();
|
||||
@@ -35,12 +44,44 @@ const HooksEditor = () => {
|
||||
<EditorNavigation />
|
||||
{snap.files.length > 0 && router.isReady ? (
|
||||
<Editor
|
||||
className="hooks-editor"
|
||||
keepCurrentModel
|
||||
defaultLanguage={snap.files?.[snap.active]?.language}
|
||||
language={snap.files?.[snap.active]?.language}
|
||||
path={snap.files?.[snap.active]?.name}
|
||||
defaultValue={snap.files?.[snap.active]?.content}
|
||||
beforeMount={(monaco) => {
|
||||
// @ts-expect-error
|
||||
window.monaco = monaco;
|
||||
monaco.languages.register({
|
||||
id: "c",
|
||||
extensions: [".c", ".h"],
|
||||
aliases: ["C", "c", "H", "h"],
|
||||
mimetypes: ["text/plain"],
|
||||
});
|
||||
MonacoServices.install(monaco);
|
||||
// create the web socket
|
||||
const webSocket = createWebSocket(
|
||||
process.env.NEXT_PUBLIC_LANGUAGE_SERVER_API_ENDPOINT || ""
|
||||
);
|
||||
// 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());
|
||||
connection.onError((error) => console.log(error));
|
||||
},
|
||||
});
|
||||
// // hook editor to global state
|
||||
// editor.updateOptions({
|
||||
// minimap: {
|
||||
// enabled: false,
|
||||
// },
|
||||
// ...snap.editorSettings,
|
||||
// });
|
||||
if (!state.editorCtx) {
|
||||
state.editorCtx = ref(monaco.editor);
|
||||
// @ts-expect-error
|
||||
@@ -51,15 +92,14 @@ const HooksEditor = () => {
|
||||
}}
|
||||
onMount={(editor, monaco) => {
|
||||
editorRef.current = editor;
|
||||
// hook editor to global state
|
||||
editor.updateOptions({
|
||||
minimap: {
|
||||
enabled: false,
|
||||
glyphMargin: true,
|
||||
lightbulb: {
|
||||
enabled: true,
|
||||
},
|
||||
...snap.editorSettings,
|
||||
});
|
||||
editor.addCommand(
|
||||
monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_S,
|
||||
monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS,
|
||||
() => {
|
||||
saveFile(editor.getValue());
|
||||
}
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
module.exports = {
|
||||
reactStrictMode: true,
|
||||
images: {
|
||||
domains: ['avatars.githubusercontent.com'],
|
||||
domains: ["avatars.githubusercontent.com"],
|
||||
},
|
||||
}
|
||||
webpack(config) {
|
||||
config.resolve.alias["vscode"] = require.resolve(
|
||||
"@codingame/monaco-languageclient/lib/vscode-compatibility"
|
||||
);
|
||||
return config;
|
||||
},
|
||||
};
|
||||
|
||||
10
package.json
10
package.json
@@ -9,6 +9,8 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@codingame/monaco-jsonrpc": "^0.3.1",
|
||||
"@codingame/monaco-languageclient": "^0.17.0",
|
||||
"@monaco-editor/react": "^4.3.1",
|
||||
"@octokit/core": "^3.5.1",
|
||||
"@radix-ui/colors": "^0.1.7",
|
||||
@@ -17,10 +19,11 @@
|
||||
"@radix-ui/react-dropdown-menu": "^0.1.1",
|
||||
"@radix-ui/react-id": "^0.1.1",
|
||||
"@stitches/react": "^1.2.6-0",
|
||||
"monaco-editor": "^0.29.1",
|
||||
"monaco-editor": "^0.30.1",
|
||||
"next": "^12.0.4",
|
||||
"next-auth": "^4.0.0-beta.5",
|
||||
"next-themes": "^0.0.15",
|
||||
"normalize-url": "^7.0.2",
|
||||
"octokit": "^1.7.0",
|
||||
"phosphor-react": "^1.3.1",
|
||||
"re-resizable": "^6.9.1",
|
||||
@@ -28,7 +31,10 @@
|
||||
"react-dom": "17.0.2",
|
||||
"react-hot-toast": "^2.1.1",
|
||||
"react-new-window": "^0.2.1",
|
||||
"valtio": "^1.2.5"
|
||||
"reconnecting-websocket": "^4.4.0",
|
||||
"valtio": "^1.2.5",
|
||||
"vscode-languageserver": "^7.0.0",
|
||||
"vscode-uri": "^3.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "17.0.31",
|
||||
|
||||
42
utils/languageClient.ts
Normal file
42
utils/languageClient.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { MessageConnection } from "@codingame/monaco-jsonrpc";
|
||||
import { MonacoLanguageClient, ErrorAction, CloseAction, createConnection } from "@codingame/monaco-languageclient";
|
||||
import normalizeUrl from "normalize-url";
|
||||
import ReconnectingWebSocket from "reconnecting-websocket";
|
||||
|
||||
export function createLanguageClient(connection: MessageConnection): MonacoLanguageClient {
|
||||
return new MonacoLanguageClient({
|
||||
name: "Sample Language Client",
|
||||
clientOptions: {
|
||||
// use a language id as a document selector
|
||||
documentSelector: ['c', 'h'],
|
||||
// disable the default error handler
|
||||
errorHandler: {
|
||||
error: () => ErrorAction.Continue,
|
||||
closed: () => CloseAction.Restart
|
||||
}
|
||||
},
|
||||
// create a language client connection from the JSON RPC connection on demand
|
||||
connectionProvider: {
|
||||
get: (errorHandler, closeHandler) => {
|
||||
return Promise.resolve(createConnection(connection, errorHandler, closeHandler))
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export function createUrl(path: string): string {
|
||||
const protocol = location.protocol === 'https:' ? 'wss' : 'ws';
|
||||
return normalizeUrl(`${protocol}://${location.host}${location.pathname}${path}`);
|
||||
}
|
||||
|
||||
export function createWebSocket(url: string): any {
|
||||
const socketOptions = {
|
||||
maxReconnectionDelay: 10000,
|
||||
minReconnectionDelay: 1000,
|
||||
reconnectionDelayGrowFactor: 1.3,
|
||||
connectionTimeout: 10000,
|
||||
maxRetries: Infinity,
|
||||
debug: false
|
||||
};
|
||||
return new ReconnectingWebSocket(url, [], socketOptions);
|
||||
}
|
||||
82
yarn.lock
82
yarn.lock
@@ -58,6 +58,24 @@
|
||||
"@babel/helper-validator-identifier" "^7.14.9"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@codingame/monaco-jsonrpc@^0.3.1":
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@codingame/monaco-jsonrpc/-/monaco-jsonrpc-0.3.1.tgz#f28dc2e27fbfe9276d2faaf40c9a572272cf3ffd"
|
||||
integrity sha512-Zxilei5fGV89uGJcFKDQFfZfUbWdP8/NGympXQUX/XRle4CYUabfvEOdY0Diq0NruttlRH3RdWVZ7Nw6f4TClQ==
|
||||
dependencies:
|
||||
vscode-jsonrpc "^6.0.0"
|
||||
|
||||
"@codingame/monaco-languageclient@^0.17.0":
|
||||
version "0.17.0"
|
||||
resolved "https://registry.yarnpkg.com/@codingame/monaco-languageclient/-/monaco-languageclient-0.17.0.tgz#ef1c42ed70392118ce4f563f6779d7bd2566b3d4"
|
||||
integrity sha512-8DZjV02STdOEy6MY24q0hQGQtoTapW7iakUbznLglCPTPyvZxUGwu8DQ5YlaBZLnrT3hPhxCmxNdoGWOnsFtqQ==
|
||||
dependencies:
|
||||
glob-to-regexp "^0.4.1"
|
||||
vscode-jsonrpc "6.0.0"
|
||||
vscode-languageclient "7.0.0"
|
||||
vscode-languageserver-textdocument "^1.0.1"
|
||||
vscode-uri "^3.0.2"
|
||||
|
||||
"@eslint/eslintrc@^0.4.3":
|
||||
version "0.4.3"
|
||||
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
|
||||
@@ -2671,10 +2689,10 @@ minimist@^1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||
|
||||
monaco-editor@^0.29.1:
|
||||
version "0.29.1"
|
||||
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.29.1.tgz#6ee93d8a5320704d48fd7058204deed72429c020"
|
||||
integrity sha512-rguaEG/zrPQSaKzQB7IfX/PpNa0qxF1FY8ZXRkN4WIl8qZdTQRSRJCtRto7IMcSgrU6H53RXI+fTcywOBC4aVw==
|
||||
monaco-editor@^0.30.1:
|
||||
version "0.30.1"
|
||||
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.30.1.tgz#47f8d18a0aa2264fc5654581741ab8d7bec01689"
|
||||
integrity sha512-B/y4+b2O5G2gjuxIFtCE2EkM17R2NM7/3F8x0qcPsqy4V83bitJTIO4TIeZpYlzu/xy6INiY/+84BEm6+7Cmzg==
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
@@ -2816,6 +2834,11 @@ normalize-path@^3.0.0, normalize-path@~3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
|
||||
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
|
||||
|
||||
normalize-url@^7.0.2:
|
||||
version "7.0.2"
|
||||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-7.0.2.tgz#3f250c964484715e6bfbcdfa2524ad76c57e1297"
|
||||
integrity sha512-HC9c6eHqxmiR6sL9DKt9ttLkiLaI1jytdkJMGAEvkLAAdlOi99kR7UMWWWRrwjucuFabaau4ZuvP1Zv+6PpDjA==
|
||||
|
||||
oauth@^0.9.15:
|
||||
version "0.9.15"
|
||||
resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1"
|
||||
@@ -3301,6 +3324,11 @@ readdirp@~3.5.0:
|
||||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
reconnecting-websocket@^4.4.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz#3b0e5b96ef119e78a03135865b8bb0af1b948783"
|
||||
integrity sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng==
|
||||
|
||||
regenerator-runtime@0.13.4:
|
||||
version "0.13.4"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz#e96bf612a3362d12bb69f7e8f74ffeab25c7ac91"
|
||||
@@ -3410,7 +3438,7 @@ semver@^6.0.0, semver@^6.3.0:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
|
||||
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
|
||||
|
||||
semver@^7.2.1, semver@^7.3.5:
|
||||
semver@^7.2.1, semver@^7.3.4, semver@^7.3.5:
|
||||
version "7.3.5"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
|
||||
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
|
||||
@@ -3848,6 +3876,50 @@ vm-browserify@1.1.2:
|
||||
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
|
||||
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
|
||||
|
||||
vscode-jsonrpc@6.0.0, vscode-jsonrpc@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz#108bdb09b4400705176b957ceca9e0880e9b6d4e"
|
||||
integrity sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==
|
||||
|
||||
vscode-languageclient@7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz#b505c22c21ffcf96e167799757fca07a6bad0fb2"
|
||||
integrity sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==
|
||||
dependencies:
|
||||
minimatch "^3.0.4"
|
||||
semver "^7.3.4"
|
||||
vscode-languageserver-protocol "3.16.0"
|
||||
|
||||
vscode-languageserver-protocol@3.16.0:
|
||||
version "3.16.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz#34135b61a9091db972188a07d337406a3cdbe821"
|
||||
integrity sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==
|
||||
dependencies:
|
||||
vscode-jsonrpc "6.0.0"
|
||||
vscode-languageserver-types "3.16.0"
|
||||
|
||||
vscode-languageserver-textdocument@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.3.tgz#879f2649bfa5a6e07bc8b392c23ede2dfbf43eff"
|
||||
integrity sha512-ynEGytvgTb6HVSUwPJIAZgiHQmPCx8bZ8w5um5Lz+q5DjP0Zj8wTFhQpyg8xaMvefDytw2+HH5yzqS+FhsR28A==
|
||||
|
||||
vscode-languageserver-types@3.16.0:
|
||||
version "3.16.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz#ecf393fc121ec6974b2da3efb3155644c514e247"
|
||||
integrity sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==
|
||||
|
||||
vscode-languageserver@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz#49b068c87cfcca93a356969d20f5d9bdd501c6b0"
|
||||
integrity sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==
|
||||
dependencies:
|
||||
vscode-languageserver-protocol "3.16.0"
|
||||
|
||||
vscode-uri@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.2.tgz#ecfd1d066cb8ef4c3a208decdbab9a8c23d055d0"
|
||||
integrity sha512-jkjy6pjU1fxUvI51P+gCsxg1u2n8LSt0W6KrCNQceaziKzff74GoWmjVG46KieVzybO1sttPQmYfrwSHey7GUA==
|
||||
|
||||
watchpack@2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.1.1.tgz#e99630550fca07df9f90a06056987baa40a689c7"
|
||||
|
||||
Reference in New Issue
Block a user