Giter Site home page Giter Site logo

mkslanc / ace-linters Goto Github PK

View Code? Open in Web Editor NEW
46.0 4.0 8.0 446.85 MB

Language-aware features for Ace Editor

Home Page: https://mkslanc.github.io/ace-linters

License: MIT License

HTML 0.27% TypeScript 99.73%
ace-editor code-completion error-checking language-support linting code-formatting lsp lua typescript language-server-protocol

ace-linters's Introduction

Ace Linters (Ace Language Client)

Ace linters is lsp client for Ace editor. It comes with large number of preconfigured easy to use in browser servers.

If you're uncertain about integrating ace-linters, consult our diagram on the GitHub Wiki for a quick setup guide tailored to your needs.

Example client with pre-defined services:

import * as ace from "ace-code";
import {Mode as TypescriptMode} from "ace-code/src/mode/typescript";
import {LanguageProvider} from "ace-linters/build/ace-linters";

// Create a web worker
let worker = new Worker(new URL('./webworker.js', import.meta.url));

// Create an Ace editor
let editor = ace.edit("container", {
    mode: new TypescriptMode() // Set the mode of the editor to Typescript
});

// Create a language provider for web worker (
let languageProvider = LanguageProvider.create(worker);

// Register the editor with the language provider
languageProvider.registerEditor(editor);

Example webworker.js with all services

New Features in 1.2.0

  • add setProviderOptions method to LanguageProvider to set options for client.
  • add experimental semantic tokens support (turned off by default). To turn on semantic tokens, set semanticTokens to true in setProviderOptions method or use it in create or fromCdn methods like that
LanguageProvider.create(worker, {functionality: {semanticTokens: true}})

New Features in 1.0.0

  • registerServer method in ServiceManager enables management of both services and servers on the web worker's side. Just add new servers to your webworker like this:
    manager.registerServer("astro", {
        module: () => import("ace-linters/build/language-client"),
        modes: "astro",
        type: "socket", // "socket|worker"
        socket: new WebSocket("ws://127.0.0.1:3030/astro"),
        initializationOptions: {
            typescript: {
                tsdk: "node_modules/typescript/lib"
            }
        }
    });
  • Multiple servers management on main thread. Just register servers like this:
    let servers = [
        {
            module: () => import("ace-linters/build/language-client"),
            modes: "astro",
            type: "socket",
            socket: new WebSocket("ws://127.0.0.1:3030/astro"),
        },
        {
            module: () => import("ace-linters/build/language-client"),
            modes: "svelte",
            type: "socket",
            socket: new WebSocket("ws://127.0.0.1:3030/svelte"),
        }
    ]
    let languageProvider = AceLanguageClient.for(servers);
  • Breaking change: AceLanguageClient.for interface was changed

Example using script tag from CDN

<script src="https://www.unpkg.com/ace-builds@latest/src-noconflict/ace.js"></script>
<script src="https://www.unpkg.com/ace-builds@latest/src-noconflict/ext-language_tools.js"></script>
<script src="https://www.unpkg.com/ace-linters@latest/build/ace-linters.js"></script>
<div id="editor" style="height: 100px">some text</div>

<script>
    ace.require("ace/ext/language_tools"); //To allow autocompletion
    var editor = ace.edit("editor", {
      enableBasicAutocompletion: true,
      enableLiveAutocompletion: true,
      mode: "ace/mode/css"
    });

    var provider = LanguageProvider.fromCdn("https://www.unpkg.com/ace-linters@latest/build/");
    provider.registerEditor(editor);
</script>

Ace linters client currently supports two modes: WebSockets and WebWorkers.

Usage with WebSocket (JSON-RPC)

In WebSockets mode, you need to start a language server on any port and connect to it.

Here's an example client:

import * as ace from "ace-code";
import {Mode as JSONMode} from "ace-code/src/mode/json"; //any mode you want
import {AceLanguageClient} from "ace-linters/build/ace-language-client";

// Create a web socket
const serverData = {
    module: () => import("ace-linters/build/language-client"),
    modes: "json|json5",
    type: "socket",
    socket: new WebSocket("ws://127.0.0.1:3000/exampleServer"), // address of your websocket server
}
// Create an Ace editor
let editor = ace.edit("container", {
    mode: new JSONMode() // Set the mode of the editor to JSON
});

// Create a language provider for web socket
let languageProvider = AceLanguageClient.for(serverData);

// Register the editor with the language provider
languageProvider.registerEditor(editor);

Full Example client

Full Example server

Usage with WebWorker (JSON-RPC)

client.js:

import * as ace from "ace-code";
import {Mode as TypescriptMode} from "ace-code/src/mode/typescript";
import {AceLanguageClient} from "ace-linters/build/ace-language-client";

// Create a web worker
let worker = new Worker(new URL('./webworker.js', import.meta.url));
const serverData = {
    module: () => import("ace-linters/build/language-client"),
    modes: "json",
    type: "webworker",
    worker: worker,
}

// Create an Ace editor
let editor = ace.edit("container", {
    mode: new TypescriptMode() // Set the mode of the editor to Typescript
});

// Create a language provider for web worker
let languageProvider = AceLanguageClient.for(serverData);

// Register the editor with the language provider
languageProvider.registerEditor(editor);

Example client

[!] You need to describe server similar to that example: Example server

Supported LSP capabilities:

  • Text Document Synchronization (with incremental changes)
  • Hover
  • Diagnostics
  • Formatting
  • Completions
  • Signature Help

Full list of capabilities

Supported languages

Ace linters supports the following languages by default with webworkers approach:

Supported languages via extensions

  • MySQL, FlinkSQL, SparkSQL, HiveSQL, TrinoSQL, PostgreSQL, Impala SQL, PL/SQL with ace-sql-linter

Installation

To install Ace linters, you can use the following command:

npm install ace-linters

License

Ace linters is released under the MIT License.

ace-linters's People

Contributors

02strich avatar anijanyan avatar janmarsicek avatar just-boris avatar mkslanc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ace-linters's Issues

Completion fails with python-lsp-server/WebSocket

I'm trying to connect with python-lsp-server and facing a few issues:

  1. Completion doesn't work. It seems toCompletions() expects a list of CompletionService but gets the actual completion response from the server (once I worked around this completion worked). This most likely broke in v0.9.0

  2. I'm getting a lot of exceptions in fromSignatureHelp():
    ace-language-client.js:19408 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'label')
    at ace-language-client.js:19408:40
    at Array.map (<anonymous>)
    at fromSignatureHelp (ace-language-client.js:19404:33)
    at ace-language-client.js:19836:141
    at signatureHelpCallback (ace-language-client.js:20548:25)
    at MessageControllerWS.callbackFunction (ace-language-client.js:20515:13)
    at MessageControllerWS.emit (ace-language-client.js:2504:5)
    at ace-language-client.js:20519:18

  3. Not a bug, but I couldn't figure out how to enable live completion with websocket/lsp server (live completion does work with the built-in completion) - is this supported?

  4. Could you please pass the options parameter to workspace/didChangeConfiguration:settings (or add a new parameter) to enable configuring the server?

Cheers
Aviv

Is there a way I can just check if there's no errors in the code?

I'm looking for something like:

if (<AceEditor>.errors.length == 0) {
    ...
}

Additionally, a way to scroll to where a specific error is, or the error nearest to the top.

It'd be great if there was an <AceEditors>.errors object/array which contained all the errors, descriptions, and line numbers.

ace-linters\build\python-service Webworker forces us to have unsafe-wasm-eval in our CSP, thus worsening security

In order to use your handy python web-worker, we have to update our CSP (Content Security Policy) to have script-src 'wasm-unsafe-eval' which akes us more vulnerable from security POV.
This is because the ace-linters\build\python-service.js file exports a huge hard-coded wasm (See screenshot below)

image

I believe the code above is generated from 'input = fetch(input)' from

Without the "wasm-unsafe-eval" add-on to our CSP, we get this error:
image

python-service.js:2 Uncaught (in promise) CompileError: WebAssembly.instantiateStreaming(): Refused to compile or instantiate WebAssembly module because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src....

Is there any chance you can update the code for the python web worker not to use wasm. i notice that the lua web-worker does not use it.
Or maybe, do you have an alternative solution to worsening our CSP?

Can´t establish a success session with gopls

Expected Behavior

We want to establish a new WebSocket connection to gopls with the ace-linter client.

Actual Behavior

Establish the connection with the WebSocket using a custom implementation or goplsws and the session is wrongly established and the linting for example not work properly.

Steps to Reproduce the Problem

  1. Try to connect to gopls (WebSocket):
import {LanguageClientConfig} from "ace-linters/types/types/language-service";
import {servFeatures} from "./config";

export let servers: LanguageClientConfig[] = [
   {
       module: () => import("ace-linters/build/language-client"),
       modes: "golang",
       type: "socket",
       socket: new WebSocket("ws://localhost:3030"),
       features: servFeatures,
       initializationOptions: {}
   },
]
export var golangContent = `
// You can edit this code!
// Click here and start typing.
package main

import "fmt"

func main() {
  fmt.Println("Hello, 世界")ssss
}

`;
import "ace-code/esm-resolver";
import {AceLanguageClient} from "ace-linters/build/ace-language-client";
import {addFormatCommand, createEditorWithLSP} from "../../editor/creation";
import {golangContent} from "../../content-examples/golang-example";
import {LanguageProvider} from "ace-linters";
import {servers} from "./servers";

let modes = [
    {
        name: "golang",
        mode: "ace/mode/golang",
        content: golangContent
    },
]

let languageProviders: LanguageProvider = AceLanguageClient.for(servers);

let i = 0;
for (let mode of modes) {
    createEditorWithLSP(mode, i, languageProviders);
    i++;
}

addFormatCommand(languageProviders);
import * as ace from "ace-code";
import "ace-code/src/ext/language_tools";
import event from "ace-code/src/lib/event";
import {HashHandler} from "ace-code/src/keyboard/hash_handler";
import keyUtil from "ace-code/src/lib/keys";
import * as theme from "ace-code/src/theme/textmate";
import type {LanguageProvider} from "ace-linters";

export function createEditorWithLSP(mode: any, i: number, languageProvider: LanguageProvider): ace.Ace.Editor {
   let el: HTMLDivElement = document.createElement("div");
   let modeName: HTMLParagraphElement = createModeNameText(el, mode.name);
   let closeButton: HTMLSpanElement = createCloseButton(el);
   let editorContainer: HTMLDivElement = document.createElement("div");
   editorContainer.setAttribute("id", "container" + i);
   editorContainer.style.height = "600px";
   el.appendChild(editorContainer);
   el.style.width = "90%";
   el.style.float = "left";
   document.body.appendChild(el);

   let editor: ace.Ace.Editor = ace.edit("container" + i, {
       mode: mode.mode,
       value: mode.content,
       relativeLineNumbers: false,
       enableAutoIndent: true,
       enableBasicAutocompletion: true,
       enableLiveAutocompletion: true,
       enableSnippets: true,
       theme: theme,
       customScrollbar: true,
   });

   editor.setTheme("ace/theme/cloud_editor_dark");

   languageProvider.registerEditor(editor);

   let options = mode.options ?? {};
   languageProvider.setSessionOptions(editor.session, options);

   closeButton.onclick = (): void => {
       languageProvider.closeDocument(editor.session);
       editor.destroy();
       editor.container.remove();
       modeName.remove();
       closeButton.remove();
   }
   return editor;
}

export function createCloseButton(el: HTMLDivElement): HTMLSpanElement {
   let closeButton: HTMLSpanElement = document.createElement("span");
   closeButton.innerText = "\u00D7";
   closeButton.style.cursor = "pointer";
   el.appendChild(closeButton);
   return closeButton;
}

export function createModeNameText(el: HTMLDivElement, name: string): HTMLParagraphElement {
   let modeName: HTMLParagraphElement = document.createElement("p");
   modeName.innerText = name;
   modeName.style.margin = "0";
   modeName.style.paddingRight = "10px";
   modeName.style.float = "left";
   el.appendChild(modeName);
   return modeName;
}

export function addFormatCommand(languageProvider: LanguageProvider): void {
   let menuKb = new HashHandler([
       {
           bindKey: "Ctrl-Shift-B",
           name: "format",
           exec: function (): void {
               languageProvider.format();
           }
       }
   ]);
   event.addCommandKeyListener(window, function (e, hashId, keyCode): void {
       let keyString = keyUtil.keyCodeToString(keyCode);
       let command = menuKb.findKeyCommand(hashId, keyString);
       if (command) {
           command.exec();
           e.preventDefault();
       }
   });
}
  1. Connection to gopls established.
  2. Start to change/edit the file in the browser with the ace client.
  3. Start to see errors when the ace client sends those changes:
  • The main error:
JSON Server: [Error - Received] 10:03:37.907 AM #1 JSON RPC parse error: DocumentURI scheme is not 'file': session1.golang
{"jsonrpc":"2.0","error":{"code":-32700,"message":"JSON RPC parse error: DocumentURI scheme is not 'file': session1.golang"},"id":1}
  • Full log:
MessageEvent {
[Symbol(kTarget)]: <ref *1> WebSocket {
    _events: [Object: null prototype] {
    close: [Array],
    message: [Function],
    error: [Function]
    },
    _eventsCount: 3,
    _maxListeners: undefined,
    _binaryType: 'nodebuffer',
    _closeCode: 1006,
    _closeFrameReceived: false,
    _closeFrameSent: false,
    _closeMessage: <Buffer >,
    _closeTimer: null,
    _extensions: {},
    _paused: false,
    _protocol: '',
    _readyState: 1,
    _receiver: Receiver {
    _events: [Object],
    _writableState: [WritableState],
    _maxListeners: undefined,
    _allowSynchronousEvents: false,
    _binaryType: 'nodebuffer',
    _extensions: {},
    _isServer: true,
    _maxPayload: 104857600,
    _skipUTF8Validation: false,
    _bufferedBytes: 0,
    _buffers: [],
    _compressed: false,
    _payloadLength: 1088,
    _mask: <Buffer 52 b8 9a f9>,
    _fragmented: 0,
    _masked: true,
    _fin: true,
    _opcode: 1,
    _totalPayloadLength: 0,
    _messageLength: 0,
    _fragments: [],
    _errored: false,
    _loop: false,
    _state: 6,
    _eventsCount: 6,
    [Symbol(shapeMode)]: true,
    [Symbol(kCapture)]: false,
    [Symbol(websocket)]: [Circular *1]
    },
    _sender: Sender {
    _extensions: {},
    _socket: [Socket],
    _firstFragment: true,
    _compress: false,
    _bufferedBytes: 0,
    _deflating: false,
    _queue: []
    },
    _socket: Socket {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: null,
    _closeAfterHandlingError: false,
    _events: [Object],
    _readableState: [ReadableState],
    _writableState: [WritableState],
    allowHalfOpen: true,
    _maxListeners: undefined,
    _eventsCount: 4,
    _sockname: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: [Server],
    _server: [Server],
    parser: null,
    on: [Function (anonymous)],
    addListener: [Function (anonymous)],
    prependListener: [Function: prependListener],
    setEncoding: [Function: socketSetEncoding],
    _paused: false,
    timeout: 0,
    [Symbol(async_id_symbol)]: 75,
    [Symbol(kHandle)]: [TCP],
    [Symbol(lastWriteQueueSize)]: 0,
    [Symbol(timeout)]: null,
    [Symbol(kBuffer)]: null,
    [Symbol(kBufferCb)]: null,
    [Symbol(kBufferGen)]: null,
    [Symbol(shapeMode)]: true,
    [Symbol(kCapture)]: false,
    [Symbol(kSetNoDelay)]: true,
    [Symbol(kSetKeepAlive)]: false,
    [Symbol(kSetKeepAliveInitialDelay)]: 0,
    [Symbol(kBytesRead)]: 0,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(websocket)]: [Circular *1]
    },
    _autoPong: true,
    _isServer: true,
    [Symbol(shapeMode)]: false,
    [Symbol(kCapture)]: false
},
[Symbol(kType)]: 'message',
[Symbol(kData)]: '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"capabilities":{"textDocument":{"hover":{"dynamicRegistration":true,"contentFormat":["markdown","plaintext"]},"synchronization":{"dynamicRegistration":true,"willSave":false,"didSave":false,"willSaveWaitUntil":false},"formatting":{"dynamicRegistration":true},"completion":{"dynamicRegistration":true,"completionItem":{"snippetSupport":true,"commitCharactersSupport":false,"documentationFormat":["markdown","plaintext"],"deprecatedSupport":false,"preselectSupport":false},"contextSupport":false},"signatureHelp":{"signatureInformation":{"documentationFormat":["markdown","plaintext"],"activeParameterSupport":true}},"documentHighlight":{"dynamicRegistration":true},"semanticTokens":{"multilineTokenSupport":false,"overlappingTokenSupport":false,"tokenTypes":[],"tokenModifiers":[],"formats":["relative"],"requests":{"full":{"delta":false},"range":true},"augmentsSyntaxTokens":true}},"workspace":{"didChangeConfiguration":{"dynamicRegistration":true}}},"initializationOptions":{},"processId":null,"rootUri":"","workspaceFolders":null}}'
}
MessageEvent {
[Symbol(kTarget)]: <ref *1> WebSocket {
    _events: [Object: null prototype] {
    close: [Array],
    message: [Function],
    error: [Function]
    },
    _eventsCount: 3,
    _maxListeners: undefined,
    _binaryType: 'nodebuffer',
    _closeCode: 1006,
    _closeFrameReceived: false,
    _closeFrameSent: false,
    _closeMessage: <Buffer >,
    _closeTimer: null,
    _extensions: {},
    _paused: false,
    _protocol: '',
    _readyState: 1,
    _receiver: Receiver {
    _events: [Object],
    _writableState: [WritableState],
    _maxListeners: undefined,
    _allowSynchronousEvents: false,
    _binaryType: 'nodebuffer',
    _extensions: {},
    _isServer: true,
    _maxPayload: 104857600,
    _skipUTF8Validation: false,
    _bufferedBytes: 712,
    _buffers: [Array],
    _compressed: false,
    _payloadLength: 86,
    _mask: <Buffer 2d e0 7e 1c>,
    _fragmented: 0,
    _masked: true,
    _fin: true,
    _opcode: 1,
    _totalPayloadLength: 0,
    _messageLength: 0,
    _fragments: [],
    _errored: false,
    _loop: false,
    _state: 6,
    _eventsCount: 6,
    [Symbol(shapeMode)]: true,
    [Symbol(kCapture)]: false,
    [Symbol(websocket)]: [Circular *1]
    },
    _sender: Sender {
    _extensions: {},
    _socket: [Socket],
    _firstFragment: true,
    _compress: false,
    _bufferedBytes: 0,
    _deflating: false,
    _queue: []
    },
    _socket: Socket {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: null,
    _closeAfterHandlingError: false,
    _events: [Object],
    _readableState: [ReadableState],
    _writableState: [WritableState],
    allowHalfOpen: true,
    _maxListeners: undefined,
    _eventsCount: 4,
    _sockname: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: [Server],
    _server: [Server],
    parser: null,
    on: [Function (anonymous)],
    addListener: [Function (anonymous)],
    prependListener: [Function: prependListener],
    setEncoding: [Function: socketSetEncoding],
    _paused: false,
    timeout: 0,
    [Symbol(async_id_symbol)]: 75,
    [Symbol(kHandle)]: [TCP],
    [Symbol(lastWriteQueueSize)]: 0,
    [Symbol(timeout)]: null,
    [Symbol(kBuffer)]: null,
    [Symbol(kBufferCb)]: null,
    [Symbol(kBufferGen)]: null,
    [Symbol(shapeMode)]: true,
    [Symbol(kCapture)]: false,
    [Symbol(kSetNoDelay)]: true,
    [Symbol(kSetKeepAlive)]: false,
    [Symbol(kSetKeepAliveInitialDelay)]: 0,
    [Symbol(kBytesRead)]: 0,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(websocket)]: [Circular *1]
    },
    _autoPong: true,
    _isServer: true,
    [Symbol(shapeMode)]: false,
    [Symbol(kCapture)]: false
},
[Symbol(kType)]: 'message',
[Symbol(kData)]: '{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{}}}'
}
MessageEvent {
[Symbol(kTarget)]: <ref *1> WebSocket {
    _events: [Object: null prototype] {
    close: [Array],
    message: [Function],
    error: [Function]
    },
    _eventsCount: 3,
    _maxListeners: undefined,
    _binaryType: 'nodebuffer',
    _closeCode: 1006,
    _closeFrameReceived: false,
    _closeFrameSent: false,
    _closeMessage: <Buffer >,
    _closeTimer: null,
    _extensions: {},
    _paused: false,
    _protocol: '',
    _readyState: 1,
    _receiver: Receiver {
    _events: [Object],
    _writableState: [WritableState],
    _maxListeners: undefined,
    _allowSynchronousEvents: false,
    _binaryType: 'nodebuffer',
    _extensions: {},
    _isServer: true,
    _maxPayload: 104857600,
    _skipUTF8Validation: false,
    _bufferedBytes: 404,
    _buffers: [Array],
    _compressed: false,
    _payloadLength: 300,
    _mask: <Buffer c5 46 97 54>,
    _fragmented: 0,
    _masked: true,
    _fin: true,
    _opcode: 1,
    _totalPayloadLength: 0,
    _messageLength: 0,
    _fragments: [],
    _errored: false,
    _loop: false,
    _state: 6,
    _eventsCount: 6,
    [Symbol(shapeMode)]: true,
    [Symbol(kCapture)]: false,
    [Symbol(websocket)]: [Circular *1]
    },
    _sender: Sender {
    _extensions: {},
    _socket: [Socket],
    _firstFragment: true,
    _compress: false,
    _bufferedBytes: 0,
    _deflating: false,
    _queue: []
    },
    _socket: Socket {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: null,
    _closeAfterHandlingError: false,
    _events: [Object],
    _readableState: [ReadableState],
    _writableState: [WritableState],
    allowHalfOpen: true,
    _maxListeners: undefined,
    _eventsCount: 4,
    _sockname: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: [Server],
    _server: [Server],
    parser: null,
    on: [Function (anonymous)],
    addListener: [Function (anonymous)],
    prependListener: [Function: prependListener],
    setEncoding: [Function: socketSetEncoding],
    _paused: false,
    timeout: 0,
    [Symbol(async_id_symbol)]: 75,
    [Symbol(kHandle)]: [TCP],
    [Symbol(lastWriteQueueSize)]: 0,
    [Symbol(timeout)]: null,
    [Symbol(kBuffer)]: null,
    [Symbol(kBufferCb)]: null,
    [Symbol(kBufferGen)]: null,
    [Symbol(shapeMode)]: true,
    [Symbol(kCapture)]: false,
    [Symbol(kSetNoDelay)]: true,
    [Symbol(kSetKeepAlive)]: false,
    [Symbol(kSetKeepAliveInitialDelay)]: 0,
    [Symbol(kBytesRead)]: 0,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(websocket)]: [Circular *1]
    },
    _autoPong: true,
    _isServer: true,
    [Symbol(shapeMode)]: false,
    [Symbol(kCapture)]: false
},
[Symbol(kType)]: 'message',
[Symbol(kData)]: '{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"session1.golang","version":1,"languageId":"golang","text":"\\n// You can edit this code!\\n// Click here and start typing.\\npackage main\\n\\nimport \\"fmt\\"\\n\\nfunc main() {\\n  fmt.Println(\\"Hello, 世界\\")ssss\\n\n\\n"}}}'
}
MessageEvent {
[Symbol(kTarget)]: <ref *1> WebSocket {
    _events: [Object: null prototype] {
    close: [Array],
    message: [Function],
    error: [Function]
    },
    _eventsCount: 3,
    _maxListeners: undefined,
    _binaryType: 'nodebuffer',
    _closeCode: 1006,
    _closeFrameReceived: false,
    _closeFrameSent: false,
    _closeMessage: <Buffer >,
    _closeTimer: null,
    _extensions: {},
    _paused: false,
    _protocol: '',
    _readyState: 1,
    _receiver: Receiver {
    _events: [Object],
    _writableState: [WritableState],
    _maxListeners: undefined,
    _allowSynchronousEvents: false,
    _binaryType: 'nodebuffer',
    _extensions: {},
    _isServer: true,
    _maxPayload: 104857600,
    _skipUTF8Validation: false,
    _bufferedBytes: 296,
    _buffers: [Array],
    _compressed: false,
    _payloadLength: 102,
    _mask: <Buffer 07 c0 2a 94>,
    _fragmented: 0,
    _masked: true,
    _fin: true,
    _opcode: 1,
    _totalPayloadLength: 0,
    _messageLength: 0,
    _fragments: [],
    _errored: false,
    _loop: false,
    _state: 6,
    _eventsCount: 6,
    [Symbol(shapeMode)]: true,
    [Symbol(kCapture)]: false,
    [Symbol(websocket)]: [Circular *1]
    },
    _sender: Sender {
    _extensions: {},
    _socket: [Socket],
    _firstFragment: true,
    _compress: false,
    _bufferedBytes: 0,
    _deflating: false,
    _queue: []
    },
    _socket: Socket {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: null,
    _closeAfterHandlingError: false,
    _events: [Object],
    _readableState: [ReadableState],
    _writableState: [WritableState],
    allowHalfOpen: true,
    _maxListeners: undefined,
    _eventsCount: 4,
    _sockname: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: [Server],
    _server: [Server],
    parser: null,
    on: [Function (anonymous)],
    addListener: [Function (anonymous)],
    prependListener: [Function: prependListener],
    setEncoding: [Function: socketSetEncoding],
    _paused: false,
    timeout: 0,
    [Symbol(async_id_symbol)]: 75,
    [Symbol(kHandle)]: [TCP],
    [Symbol(lastWriteQueueSize)]: 0,
    [Symbol(timeout)]: null,
    [Symbol(kBuffer)]: null,
    [Symbol(kBufferCb)]: null,
    [Symbol(kBufferGen)]: null,
    [Symbol(shapeMode)]: true,
    [Symbol(kCapture)]: false,
    [Symbol(kSetNoDelay)]: true,
    [Symbol(kSetKeepAlive)]: false,
    [Symbol(kSetKeepAliveInitialDelay)]: 0,
    [Symbol(kBytesRead)]: 0,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(websocket)]: [Circular *1]
    },
    _autoPong: true,
    _isServer: true,
    [Symbol(shapeMode)]: false,
    [Symbol(kCapture)]: false
},
[Symbol(kType)]: 'message',
[Symbol(kData)]: '{"jsonrpc":"2.0","method":"textDocument/didClose","params":{"textDocument":{"uri":"session1.golang"}}}'
}
MessageEvent {
[Symbol(kTarget)]: <ref *1> WebSocket {
    _events: [Object: null prototype] {
    close: [Array],
    message: [Function],
    error: [Function]
    },
    _eventsCount: 3,
    _maxListeners: undefined,
    _binaryType: 'nodebuffer',
    _closeCode: 1006,
    _closeFrameReceived: false,
    _closeFrameSent: false,
    _closeMessage: <Buffer >,
    _closeTimer: null,
    _extensions: {},
    _paused: false,
    _protocol: '',
    _readyState: 1,
    _receiver: Receiver {
    _events: [Object],
    _writableState: [WritableState],
    _maxListeners: undefined,
    _allowSynchronousEvents: false,
    _binaryType: 'nodebuffer',
    _extensions: {},
    _isServer: true,
    _maxPayload: 104857600,
    _skipUTF8Validation: false,
    _bufferedBytes: 0,
    _buffers: [],
    _compressed: false,
    _payloadLength: 288,
    _mask: <Buffer 7c c9 a5 53>,
    _fragmented: 0,
    _masked: true,
    _fin: true,
    _opcode: 1,
    _totalPayloadLength: 0,
    _messageLength: 0,
    _fragments: [],
    _errored: false,
    _loop: false,
    _state: 6,
    _eventsCount: 6,
    [Symbol(shapeMode)]: true,
    [Symbol(kCapture)]: false,
    [Symbol(websocket)]: [Circular *1]
    },
    _sender: Sender {
    _extensions: {},
    _socket: [Socket],
    _firstFragment: true,
    _compress: false,
    _bufferedBytes: 0,
    _deflating: false,
    _queue: []
    },
    _socket: Socket {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: null,
    _closeAfterHandlingError: false,
    _events: [Object],
    _readableState: [ReadableState],
    _writableState: [WritableState],
    allowHalfOpen: true,
    _maxListeners: undefined,
    _eventsCount: 4,
    _sockname: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: [Server],
    _server: [Server],
    parser: null,
    on: [Function (anonymous)],
    addListener: [Function (anonymous)],
    prependListener: [Function: prependListener],
    setEncoding: [Function: socketSetEncoding],
    _paused: false,
    timeout: 0,
    [Symbol(async_id_symbol)]: 75,
    [Symbol(kHandle)]: [TCP],
    [Symbol(lastWriteQueueSize)]: 0,
    [Symbol(timeout)]: null,
    [Symbol(kBuffer)]: null,
    [Symbol(kBufferCb)]: null,
    [Symbol(kBufferGen)]: null,
    [Symbol(shapeMode)]: true,
    [Symbol(kCapture)]: false,
    [Symbol(kSetNoDelay)]: true,
    [Symbol(kSetKeepAlive)]: false,
    [Symbol(kSetKeepAliveInitialDelay)]: 0,
    [Symbol(kBytesRead)]: 0,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(websocket)]: [Circular *1]
    },
    _autoPong: true,
    _isServer: true,
    [Symbol(shapeMode)]: false,
    [Symbol(kCapture)]: false
},
[Symbol(kType)]: 'message',
[Symbol(kData)]: '{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"session1.golang","languageId":"golang","text":"\\n// You can edit this code!\\n// Click here and start typing.\\npackage main\\n\\nimport \\"fmt\\"\\n\\nfunc main() {\\n  fmt.Println(\\"Hello, 世界\\")ssss\\n}\\n\\n"}}}'
}
JSON Server: [Trace - 10:03:36.462 AM] Sending request 'initialize - (0)'.
Params: {"capabilities":{"textDocument":{"hover":{"dynamicRegistration":true,"contentFormat":["markdown","plaintext"]},"synchronization":{"dynamicRegistration":true,"willSave":false,"didSave":false,"willSaveWaitUntil":false},"formatting":{"dynamicRegistration":true},"completion":{"dynamicRegistration":true,"completionItem":{"snippetSupport":true,"commitCharactersSupport":false,"documentationFormat":["markdown","plaintext"],"deprecatedSupport":false,"preselectSupport":false},"contextSupport":false},"signatureHelp":{"signatureInformation":{"documentationFormat":["markdown","plaintext"],"activeParameterSupport":true}},"documentHighlight":{"dynamicRegistration":true},"semanticTokens":{"multilineTokenSupport":false,"overlappingTokenSupport":false,"tokenTypes":[],"tokenModifiers":[],"formats":["relative"],"requests":{"full":{"delta":false},"range":true},"augmentsSyntaxTokens":true}},"workspace":{"didChangeConfiguration":{"dynamicRegistration":true}}},"initializationOptions":{},"processId":274438,"rootUri":"","workspaceFolders":null}


[Trace - 10:03:36.464 AM] Received response 'initialize - (0)' in 2ms.
Result: {"capabilities":{"textDocumentSync":{"openClose":true,"change":2,"save":{}},"completionProvider":{"triggerCharacters":["."]},"hoverProvider":true,"signatureHelpProvider":{"triggerCharacters":["(",","]},"definitionProvider":true,"typeDefinitionProvider":true,"implementationProvider":true,"referencesProvider":true,"documentHighlightProvider":true,"documentSymbolProvider":true,"codeActionProvider":true,"codeLensProvider":{},"documentLinkProvider":{},"workspaceSymbolProvider":true,"documentFormattingProvider":true,"renameProvider":true,"foldingRangeProvider":true,"selectionRangeProvider":true,"executeCommandProvider":{"commands":["gopls.add_dependency","gopls.add_import","gopls.add_telemetry_counters","gopls.apply_fix","gopls.change_signature","gopls.check_upgrades","gopls.diagnose_files","gopls.edit_go_directive","gopls.fetch_vulncheck_result","gopls.gc_details","gopls.generate","gopls.go_get_package","gopls.list_imports","gopls.list_known_packages","gopls.maybe_prompt_for_telemetry","gopls.mem_stats","gopls.regenerate_cgo","gopls.remove_dependency","gopls.reset_go_mod_diagnostics","gopls.run_go_work_command","gopls.run_govulncheck","gopls.run_tests","gopls.start_debugging","gopls.start_profile","gopls.stop_profile","gopls.test","gopls.tidy","gopls.toggle_gc_details","gopls.update_go_sum","gopls.upgrade_dependency","gopls.vendor","gopls.views","gopls.workspace_stats"]},"callHierarchyProvider":true,"semanticTokensProvider":{"legend":{"tokenTypes":[],"tokenModifiers":[]},"range":true,"full":true},"inlayHintProvider":{},"workspace":{"workspaceFolders":{"supported":true,"changeNotifications":"workspace/didChangeWorkspaceFolders"}}},"serverInfo":{"name":"gopls","version":"{\"GoVersion\":\"go1.22.2\",\"Path\":\"golang.org/x/tools/gopls\",\"Main\":{\"Path\":\"golang.org/x/tools/gopls\",\"Version\":\"v0.15.2\",\"Sum\":\"h1:4JKt4inO8JaFW3l/Fh9X1k/5JQn+iUOpdc4/Lpi0mOs=\",\"Replace\":null},\"Deps\":[{\"Path\":\"github.com/BurntSushi/toml\",\"Version\":\"v1.2.1\",\"Sum\":\"h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=\",\"Replace\":null},{\"Path\":\"github.com/google/go-cmp\",\"Version\":\"v0.6.0\",\"Sum\":\"h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\",\"Replace\":null},{\"Path\":\"golang.org/x/exp/typeparams\",\"Version\":\"v0.0.0-20221212164502-fae10dda9338\",\"Sum\":\"h1:2O2DON6y3XMJiQRAS1UWU+54aec2uopH3x7MAiqGW6Y=\",\"Replace\":null},{\"Path\":\"golang.org/x/mod\",\"Version\":\"v0.15.0\",\"Sum\":\"h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=\",\"Replace\":null},{\"Path\":\"golang.org/x/sync\",\"Version\":\"v0.6.0\",\"Sum\":\"h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=\",\"Replace\":null},{\"Path\":\"golang.org/x/telemetry\",\"Version\":\"v0.0.0-20240209200032-7b892fcb8a78\",\"Sum\":\"h1:vcVnuftN4J4UKLRcgetjzfU9FjjgXUUYUc3JhFplgV4=\",\"Replace\":null},{\"Path\":\"golang.org/x/text\",\"Version\":\"v0.14.0\",\"Sum\":\"h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=\",\"Replace\":null},{\"Path\":\"golang.org/x/tools\",\"Version\":\"v0.18.1-0.20240311201521-78fbdeb61842\",\"Sum\":\"h1:No0LMXYFkp3j4oEsPdtY8LUQz33gu79Rm9DE+izMeGQ=\",\"Replace\":null},{\"Path\":\"golang.org/x/vuln\",\"Version\":\"v1.0.1\",\"Sum\":\"h1:KUas02EjQK5LTuIx1OylBQdKKZ9jeugs+HiqO5HormU=\",\"Replace\":null},{\"Path\":\"honnef.co/go/tools\",\"Version\":\"v0.4.6\",\"Sum\":\"h1:oFEHCKeID7to/3autwsWfnuv69j3NsfcXbvJKuIcep8=\",\"Replace\":null},{\"Path\":\"mvdan.cc/gofumpt\",\"Version\":\"v0.6.0\",\"Sum\":\"h1:G3QvahNDmpD+Aek/bNOLrFR2XC6ZAdo62dZu65gmwGo=\",\"Replace\":null},{\"Path\":\"mvdan.cc/xurls/v2\",\"Version\":\"v2.5.0\",\"Sum\":\"h1:lyBNOm8Wo71UknhUs4QTFUNNMyxy2JEIaKKo0RWOh+8=\",\"Replace\":null}],\"Settings\":[{\"Key\":\"-buildmode\",\"Value\":\"exe\"},{\"Key\":\"-compiler\",\"Value\":\"gc\"},{\"Key\":\"DefaultGODEBUG\",\"Value\":\"httplaxcontentlength=1,httpmuxgo121=1,panicnil=1,tls10server=1,tlsrsakex=1,tlsunsafeekm=1\"},{\"Key\":\"CGO_ENABLED\",\"Value\":\"1\"},{\"Key\":\"CGO_CFLAGS\",\"Value\":\"-I/opt/altair-libs -O0 -g\"},{\"Key\":\"CGO_CPPFLAGS\",\"Value\":\"\"},{\"Key\":\"CGO_CXXFLAGS\",\"Value\":\"\"},{\"Key\":\"CGO_LDFLAGS\",\"Value\":\"-L/opt/altair-libs -llmx-altair -laljdk\"},{\"Key\":\"GOARCH\",\"Value\":\"amd64\"},{\"Key\":\"GOOS\",\"Value\":\"linux\"},{\"Key\":\"GOAMD64\",\"Value\":\"v1\"}],\"Version\":\"v0.15.2\"}"}}


[Trace - 10:03:36.464 AM] Sending notification 'workspace/didChangeConfiguration'.
Params: {"settings":{}}


[Trace - 10:03:36.464 AM] Sending notification 'textDocument/didOpen'.
Params: {"textDocument":{"uri":"session1.golang","version":1,"languageId":"golang","text":"\n// You can edit this code!\n// Click here and start typing.\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  fmt.Println(\"Hello, 世界\")ssss\n}\n\n"}}


[Trace - 10:03:36.465 AM] Sending notification 'textDocument/didClose'.
Params: {"textDocument":{"uri":"session1.golang"}}


[Trace - 10:03:36.465 AM] Sending notification 'textDocument/didOpen'.
Params: {"textDocument":{"uri":"session1.golang","languageId":"golang","text":"\n// You can edit this code!\n// Click here and start typing.\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n  fmt.Println(\"Hello, 世界\")ssss\n}\n\n"}}



{"jsonrpc":"2.0","result":{"capabilities":{"textDocumentSync":{"openClose":true,"change":2,"save":{}},"completionProvider":{"triggerCharacters":["."]},"hoverProvider":true,"signatureHelpProvider":{"triggerCharacters":["(",","]},"definitionProvider":true,"typeDefinitionProvider":true,"implementationProvider":true,"referencesProvider":true,"documentHighlightProvider":true,"documentSymbolProvider":true,"codeActionProvider":true,"codeLensProvider":{},"documentLinkProvider":{},"workspaceSymbolProvider":true,"documentFormattingProvider":true,"renameProvider":true,"foldingRangeProvider":true,"selectionRangeProvider":true,"executeCommandProvider":{"commands":["gopls.add_dependency","gopls.add_import","gopls.add_telemetry_counters","gopls.apply_fix","gopls.change_signature","gopls.check_upgrades","gopls.diagnose_files","gopls.edit_go_directive","gopls.fetch_vulncheck_result","gopls.gc_details","gopls.generate","gopls.go_get_package","gopls.list_imports","gopls.list_known_packages","gopls.maybe_prompt_for_telemetry","gopls.mem_stats","gopls.regenerate_cgo","gopls.remove_dependency","gopls.reset_go_mod_diagnostics","gopls.run_go_work_command","gopls.run_govulncheck","gopls.run_tests","gopls.start_debugging","gopls.start_profile","gopls.stop_profile","gopls.test","gopls.tidy","gopls.toggle_gc_details","gopls.update_go_sum","gopls.upgrade_dependency","gopls.vendor","gopls.views","gopls.workspace_stats"]},"callHierarchyProvider":true,"semanticTokensProvider":{"legend":{"tokenTypes":[],"tokenModifiers":[]},"range":true,"full":true},"inlayHintProvider":{},"workspace":{"workspaceFolders":{"supported":true,"changeNotifications":"workspace/didChangeWorkspaceFolders"}}},"serverInfo":{"name":"gopls","version":"{\"GoVersion\":\"go1.22.2\",\"Path\":\"golang.org/x/tools/gopls\",\"Main\":{\"Path\":\"golang.org/x/tools/gopls\",\"Version\":\"v0.15.2\",\"Sum\":\"h1:4JKt4inO8JaFW3l/Fh9X1k/5JQn+iUOpdc4/Lpi0mOs=\",\"Replace\":null},\"Deps\":[{\"Path\":\"github.com/BurntSushi/toml\",\"Version\":\"v1.2.1\",\"Sum\":\"h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=\",\"Replace\":null},{\"Path\":\"github.com/google/go-cmp\",\"Version\":\"v0.6.0\",\"Sum\":\"h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=\",\"Replace\":null},{\"Path\":\"golang.org/x/exp/typeparams\",\"Version\":\"v0.0.0-20221212164502-fae10dda9338\",\"Sum\":\"h1:2O2DON6y3XMJiQRAS1UWU+54aec2uopH3x7MAiqGW6Y=\",\"Replace\":null},{\"Path\":\"golang.org/x/mod\",\"Version\":\"v0.15.0\",\"Sum\":\"h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=\",\"Replace\":null},{\"Path\":\"golang.org/x/sync\",\"Version\":\"v0.6.0\",\"Sum\":\"h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=\",\"Replace\":null},{\"Path\":\"golang.org/x/telemetry\",\"Version\":\"v0.0.0-20240209200032-7b892fcb8a78\",\"Sum\":\"h1:vcVnuftN4J4UKLRcgetjzfU9FjjgXUUYUc3JhFplgV4=\",\"Replace\":null},{\"Path\":\"golang.org/x/text\",\"Version\":\"v0.14.0\",\"Sum\":\"h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=\",\"Replace\":null},{\"Path\":\"golang.org/x/tools\",\"Version\":\"v0.18.1-0.20240311201521-78fbdeb61842\",\"Sum\":\"h1:No0LMXYFkp3j4oEsPdtY8LUQz33gu79Rm9DE+izMeGQ=\",\"Replace\":null},{\"Path\":\"golang.org/x/vuln\",\"Version\":\"v1.0.1\",\"Sum\":\"h1:KUas02EjQK5LTuIx1OylBQdKKZ9jeugs+HiqO5HormU=\",\"Replace\":null},{\"Path\":\"honnef.co/go/tools\",\"Version\":\"v0.4.6\",\"Sum\":\"h1:oFEHCKeID7to/3autwsWfnuv69j3NsfcXbvJKuIcep8=\",\"Replace\":null},{\"Path\":\"mvdan.cc/gofumpt\",\"Version\":\"v0.6.0\",\"Sum\":\"h1:G3QvahNDmpD+Aek/bNOLrFR2XC6ZAdo62dZu65gmwGo=\",\"Replace\":null},{\"Path\":\"mvdan.cc/xurls/v2\",\"Version\":\"v2.5.0\",\"Sum\":\"h1:lyBNOm8Wo71UknhUs4QTFUNNMyxy2JEIaKKo0RWOh+8=\",\"Replace\":null}],\"Settings\":[{\"Key\":\"-buildmode\",\"Value\":\"exe\"},{\"Key\":\"-compiler\",\"Value\":\"gc\"},{\"Key\":\"DefaultGODEBUG\",\"Value\":\"httplaxcontentlength=1,httpmuxgo121=1,panicnil=1,tls10server=1,tlsrsakex=1,tlsunsafeekm=1\"},{\"Key\":\"CGO_ENABLED\",\"Value\":\"1\"},{\"Key\":\"CGO_CFLAGS\",\"Value\":\"-I/opt/altair-libs -O0 -g\"},{\"Key\":\"CGO_CPPFLAGS\",\"Value\":\"\"},{\"Key\":\"CGO_CXXFLAGS\",\"Value\":\"\"},{\"Key\":\"CGO_LDFLAGS\",\"Value\":\"-L/opt/altair-libs -llmx-altair -laljdk\"},{\"Key\":\"GOARCH\",\"Value\":\"amd64\"},{\"Key\":\"GOOS\",\"Value\":\"linux\"},{\"Key\":\"GOAMD64\",\"Value\":\"v1\"}],\"Version\":\"v0.15.2\"}"}},"id":0}
MessageEvent {
[Symbol(kTarget)]: <ref *1> WebSocket {
    _events: [Object: null prototype] {
    close: [Array],
    message: [Function],
    error: [Function]
    },
    _eventsCount: 3,
    _maxListeners: undefined,
    _binaryType: 'nodebuffer',
    _closeCode: 1006,
    _closeFrameReceived: false,
    _closeFrameSent: false,
    _closeMessage: <Buffer >,
    _closeTimer: null,
    _extensions: {},
    _paused: false,
    _protocol: '',
    _readyState: 1,
    _receiver: Receiver {
    _events: [Object],
    _writableState: [WritableState],
    _maxListeners: undefined,
    _allowSynchronousEvents: false,
    _binaryType: 'nodebuffer',
    _extensions: {},
    _isServer: true,
    _maxPayload: 104857600,
    _skipUTF8Validation: false,
    _bufferedBytes: 0,
    _buffers: [],
    _compressed: false,
    _payloadLength: 52,
    _mask: <Buffer 81 0c 0a 55>,
    _fragmented: 0,
    _masked: true,
    _fin: true,
    _opcode: 1,
    _totalPayloadLength: 0,
    _messageLength: 0,
    _fragments: [],
    _errored: false,
    _loop: false,
    _state: 6,
    _eventsCount: 6,
    [Symbol(shapeMode)]: true,
    [Symbol(kCapture)]: false,
    [Symbol(websocket)]: [Circular *1]
    },
    _sender: Sender {
    _extensions: {},
    _socket: [Socket],
    _firstFragment: true,
    _compress: false,
    _bufferedBytes: 0,
    _deflating: false,
    _queue: []
    },
    _socket: Socket {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: null,
    _closeAfterHandlingError: false,
    _events: [Object],
    _readableState: [ReadableState],
    _writableState: [WritableState],
    allowHalfOpen: true,
    _maxListeners: undefined,
    _eventsCount: 4,
    _sockname: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: [Server],
    _server: [Server],
    parser: null,
    on: [Function (anonymous)],
    addListener: [Function (anonymous)],
    prependListener: [Function: prependListener],
    setEncoding: [Function: socketSetEncoding],
    _paused: false,
    timeout: 0,
    [Symbol(async_id_symbol)]: 75,
    [Symbol(kHandle)]: [TCP],
    [Symbol(lastWriteQueueSize)]: 0,
    [Symbol(timeout)]: null,
    [Symbol(kBuffer)]: null,
    [Symbol(kBufferCb)]: null,
    [Symbol(kBufferGen)]: null,
    [Symbol(shapeMode)]: true,
    [Symbol(kCapture)]: false,
    [Symbol(kSetNoDelay)]: true,
    [Symbol(kSetKeepAlive)]: false,
    [Symbol(kSetKeepAliveInitialDelay)]: 0,
    [Symbol(kBytesRead)]: 0,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(websocket)]: [Circular *1]
    },
    _autoPong: true,
    _isServer: true,
    [Symbol(shapeMode)]: false,
    [Symbol(kCapture)]: false
},
[Symbol(kType)]: 'message',
[Symbol(kData)]: '{"jsonrpc":"2.0","method":"initialized","params":{}}'
}
MessageEvent {
[Symbol(kTarget)]: <ref *1> WebSocket {
    _events: [Object: null prototype] {
    close: [Array],
    message: [Function],
    error: [Function]
    },
    _eventsCount: 3,
    _maxListeners: undefined,
    _binaryType: 'nodebuffer',
    _closeCode: 1006,
    _closeFrameReceived: false,
    _closeFrameSent: false,
    _closeMessage: <Buffer >,
    _closeTimer: null,
    _extensions: {},
    _paused: false,
    _protocol: '',
    _readyState: 1,
    _receiver: Receiver {
    _events: [Object],
    _writableState: [WritableState],
    _maxListeners: undefined,
    _allowSynchronousEvents: false,
    _binaryType: 'nodebuffer',
    _extensions: {},
    _isServer: true,
    _maxPayload: 104857600,
    _skipUTF8Validation: false,
    _bufferedBytes: 0,
    _buffers: [],
    _compressed: false,
    _payloadLength: 86,
    _mask: <Buffer d7 82 8c 0f>,
    _fragmented: 0,
    _masked: true,
    _fin: true,
    _opcode: 1,
    _totalPayloadLength: 0,
    _messageLength: 0,
    _fragments: [],
    _errored: false,
    _loop: false,
    _state: 6,
    _eventsCount: 6,
    [Symbol(shapeMode)]: true,
    [Symbol(kCapture)]: false,
    [Symbol(websocket)]: [Circular *1]
    },
    _sender: Sender {
    _extensions: {},
    _socket: [Socket],
    _firstFragment: true,
    _compress: false,
    _bufferedBytes: 0,
    _deflating: false,
    _queue: []
    },
    _socket: Socket {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: null,
    _closeAfterHandlingError: false,
    _events: [Object],
    _readableState: [ReadableState],
    _writableState: [WritableState],
    allowHalfOpen: true,
    _maxListeners: undefined,
    _eventsCount: 4,
    _sockname: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: [Server],
    _server: [Server],
    parser: null,
    on: [Function (anonymous)],
    addListener: [Function (anonymous)],
    prependListener: [Function: prependListener],
    setEncoding: [Function: socketSetEncoding],
    _paused: false,
    timeout: 0,
    [Symbol(async_id_symbol)]: 75,
    [Symbol(kHandle)]: [TCP],
    [Symbol(lastWriteQueueSize)]: 0,
    [Symbol(timeout)]: null,
    [Symbol(kBuffer)]: null,
    [Symbol(kBufferCb)]: null,
    [Symbol(kBufferGen)]: null,
    [Symbol(shapeMode)]: true,
    [Symbol(kCapture)]: false,
    [Symbol(kSetNoDelay)]: true,
    [Symbol(kSetKeepAlive)]: false,
    [Symbol(kSetKeepAliveInitialDelay)]: 0,
    [Symbol(kBytesRead)]: 0,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(websocket)]: [Circular *1]
    },
    _autoPong: true,
    _isServer: true,
    [Symbol(shapeMode)]: false,
    [Symbol(kCapture)]: false
},
[Symbol(kType)]: 'message',
[Symbol(kData)]: '{"jsonrpc":"2.0","method":"workspace/didChangeConfiguration","params":{"settings":{}}}'
}
JSON Server: [Trace - 10:03:36.580 AM] Sending notification 'initialized'.
Params: {}



JSON Server: [Trace - 10:03:36.581 AM] Sending notification 'workspace/didChangeConfiguration'.
Params: {"settings":{}}



MessageEvent {
[Symbol(kTarget)]: <ref *1> WebSocket {
    _events: [Object: null prototype] {
    close: [Array],
    message: [Function],
    error: [Function]
    },
    _eventsCount: 3,
    _maxListeners: undefined,
    _binaryType: 'nodebuffer',
    _closeCode: 1006,
    _closeFrameReceived: false,
    _closeFrameSent: false,
    _closeMessage: <Buffer >,
    _closeTimer: null,
    _extensions: {},
    _paused: false,
    _protocol: '',
    _readyState: 1,
    _receiver: Receiver {
    _events: [Object],
    _writableState: [WritableState],
    _maxListeners: undefined,
    _allowSynchronousEvents: false,
    _binaryType: 'nodebuffer',
    _extensions: {},
    _isServer: true,
    _maxPayload: 104857600,
    _skipUTF8Validation: false,
    _bufferedBytes: 0,
    _buffers: [],
    _compressed: false,
    _payloadLength: 155,
    _mask: <Buffer 53 79 0e 4d>,
    _fragmented: 0,
    _masked: true,
    _fin: true,
    _opcode: 1,
    _totalPayloadLength: 0,
    _messageLength: 0,
    _fragments: [],
    _errored: false,
    _loop: false,
    _state: 6,
    _eventsCount: 6,
    [Symbol(shapeMode)]: true,
    [Symbol(kCapture)]: false,
    [Symbol(websocket)]: [Circular *1]
    },
    _sender: Sender {
    _extensions: {},
    _socket: [Socket],
    _firstFragment: true,
    _compress: false,
    _bufferedBytes: 0,
    _deflating: false,
    _queue: []
    },
    _socket: Socket {
    connecting: false,
    _hadError: false,
    _parent: null,
    _host: null,
    _closeAfterHandlingError: false,
    _events: [Object],
    _readableState: [ReadableState],
    _writableState: [WritableState],
    allowHalfOpen: true,
    _maxListeners: undefined,
    _eventsCount: 4,
    _sockname: null,
    _pendingData: null,
    _pendingEncoding: '',
    server: [Server],
    _server: [Server],
    parser: null,
    on: [Function (anonymous)],
    addListener: [Function (anonymous)],
    prependListener: [Function: prependListener],
    setEncoding: [Function: socketSetEncoding],
    _paused: false,
    timeout: 0,
    [Symbol(async_id_symbol)]: 75,
    [Symbol(kHandle)]: [TCP],
    [Symbol(lastWriteQueueSize)]: 0,
    [Symbol(timeout)]: null,
    [Symbol(kBuffer)]: null,
    [Symbol(kBufferCb)]: null,
    [Symbol(kBufferGen)]: null,
    [Symbol(shapeMode)]: true,
    [Symbol(kCapture)]: false,
    [Symbol(kSetNoDelay)]: true,
    [Symbol(kSetKeepAlive)]: false,
    [Symbol(kSetKeepAliveInitialDelay)]: 0,
    [Symbol(kBytesRead)]: 0,
    [Symbol(kBytesWritten)]: 0,
    [Symbol(websocket)]: [Circular *1]
    },
    _autoPong: true,
    _isServer: true,
    [Symbol(shapeMode)]: false,
    [Symbol(kCapture)]: false
},
[Symbol(kType)]: 'message',
[Symbol(kData)]: '{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"session1.golang"},"position":{"line":8,"character":30}}}'
}
JSON Server: [Trace - 10:03:37.907 AM] Sending request 'textDocument/documentHighlight - (1)'.
Params: {"textDocument":{"uri":"session1.golang"},"position":{"line":8,"character":30}}



JSON Server: [Error - Received] 10:03:37.907 AM #1 JSON RPC parse error: DocumentURI scheme is not 'file': session1.golang



{"jsonrpc":"2.0","error":{"code":-32700,"message":"JSON RPC parse error: DocumentURI scheme is not 'file': session1.golang"},"id":1}

Specifications

  • Versions:
    • ace-code: v1.33.0
    • ace-linters: v1.2.0
    • vscode-ws-jsonrpc: v3.3.1,
    • node.js: v20.12.2
    • npm: v10.5.0
    • gopls: v0.15.2
  • Platform:
    • OS: Kubuntu 23.10 - Kernel v6.5.0

Can be a misconfiguration or bad server connection establishment?

fromSignatureHelp exception with lsp server (might be react-ace related)

Hi, I'm testing with react-ace and python-lsp-server and got several exceptions in fromSignatureHelp (signatureIndex ==0, el == []).
However, upon further debugging it seems the trigger was the react-ace component being updated with a different value than the initial value (this also caused the lsp server to lose sync with the document).

Fixing the react-ace initialisation fixed the issue, but it seems ace-linters is not guarded against this scenario - is there a way to guard against it?

Question about multiple editors.

Hello, i have a question about this awesome project.

Can the linter support multiple file modules ?
Like i want to put in my editor a typescript file with an import. Can it be also parsed ? Is it possible to add files like that without creating an editor ?

Best regards.

Autocomplete replacement ranges are incorrect?

As a helpful tester pointed out on my project...

Ryex/ic10emu#3

Autocomplete replacements seems to incorrect, the last character entered before the replacement was accepted gets placed in front.

Project is live at https://ryex.github.io/ic10emu/ so you can try to replicate the issue yourself. I have the LSP messages logged in the console so I can see that the message is well formed as screenshot in the linked issue

Basic example doesn't even work

From README.md:

<script src="https://www.unpkg.com/ace-builds@latest/src-noconflict/ace.js"></script>
<script src="https://www.unpkg.com/ace-builds@latest/src-noconflict/ext-language_tools.js"></script>
<script src="https://www.unpkg.com/ace-linters@latest/build/ace-linters.js"></script>
<div id="editor" style="height: 100px">some text</div>

<script>
    ace.require("ace/ext/language_tools"); //To allow autocompletion
    var CssMode = ace.require("ace/mode/css").Mode;
    var editor = ace.edit("editor", {
        enableBasicAutocompletion: true,
        enableLiveAutocompletion: true,
        mode: new CssMode()
    });

    var provider = LanguageProvider.fromCdn("https://www.unpkg.com/ace-linters@latest/build/");
    provider.registerEditor(editor);
</script>

Error: Uncaught TypeError: Cannot read properties of undefined (reading 'Mode')

image

I suggest to kick out TS and use pure ESM with JSDoc, that speeds up your dev cycle and probably preventing bugs like this.

Unusable through websocket

I have tried both mode of ace-linter and
According to me , ace-linter is not practically usable through websocket , here are problems:

  • A lots of error in the console(but it work and provide LSP) which makes it laggy
  • in some case it's completions are not visible in autocompletion box (mainly in svelte mode while typing any html element)
  • and many LSP servers are not compatible yet with ace-linters such as rust-analyzer

Note
These errors are faced in case of multiple languages(like python, svelte) and through webworker there is no any complain and it works smoothly

MessageController doesn't handle changeMode correctly

in MessageController::init there is

        this.on(MessageType.validate.toString() + "-" + sessionId, validationCallback);

where sessionId is a string containing the current Mode. But when the Mode of the session Changes, this event Listener isn't updated.

This leads to missing validation if you set the Mode only after you've initialized the Language Provider.

So i propose doing something like:

// message-controller.ts

    changeMode(sessionId: string, value: string, mode: string, callback?: (capabilities) => void) {
        // TODO remove the old event listener
        this.on(MessageType.validate.toString() + "-" + sessionId, validationCallback);
        
        this.postMessage(new ChangeModeMessage(sessionId, value, mode), callback);
    }

Tootltips break when used under a web-component with ace attached to a shadow-dom

I was working to use Ace under a web component and attached to a shadow dom

(see https://github.com/F0rce/lit-ace for an example component)

This actually works great. right up until I go to see a hover tooltip and realize they don't show up.

Inspecting the dom tree shows the tool-tips attached to the main document body and not updating.
image

Hovering too much gets a error on the console about detecting an EventEmitter memory leak

lspWorker.ts:214 Client Message: {jsonrpc: '2.0', id: 4, method: 'textDocument/signatureHelp', params: {…}}
lspWorker.ts:214 Client Message: {jsonrpc: '2.0', id: 5, method: 'textDocument/hover', params: {…}}
lspWorker.ts:214 Client Message: {jsonrpc: '2.0', id: 6, method: 'textDocument/hover', params: {…}}
lspWorker.ts:214 Client Message: {jsonrpc: '2.0', id: 7, method: 'textDocument/hover', params: {…}}
lspWorker.ts:214 Client Message: {jsonrpc: '2.0', id: 8, method: 'textDocument/hover', params: {…}}
lspWorker.ts:214 Client Message: {jsonrpc: '2.0', id: 9, method: 'textDocument/hover', params: {…}}
lspWorker.ts:214 Client Message: {jsonrpc: '2.0', id: 10, method: 'textDocument/hover', params: {…}}
lspWorker.ts:214 Client Message: {jsonrpc: '2.0', id: 11, method: 'textDocument/hover', params: {…}}
lspWorker.ts:214 Client Message: {jsonrpc: '2.0', id: 12, method: 'textDocument/hover', params: {…}}
ace-language-client.js:2397  MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 5-session2.ic10 listeners added. Use emitter.setMaxListeners() to increase limit
    at _addListener (webpack-internal:///./node_modules/.pnpm/[email protected]/node_modules/ace-linters/build/ace-language-client.js:2557:15)
    at MessageController.addListener (webpack-internal:///./node_modules/.pnpm/[email protected]/node_modules/ace-linters/build/ace-language-client.js:2573:10)
    at MessageController.postMessage (webpack-internal:///./node_modules/.pnpm/[email protected]/node_modules/ace-linters/build/ace-language-client.js:19448:18)
    at MessageController.doHover (webpack-internal:///./node_modules/.pnpm/[email protected]/node_modules/ace-linters/build/ace-language-client.js:19405:14)
    at LanguageProvider.doHover (webpack-internal:///./node_modules/.pnpm/[email protected]/node_modules/ace-linters/build/ace-language-client.js:20695:33)
    at HoverTooltip.eval [as $gatherData] (webpack-internal:///./node_modules/.pnpm/[email protected]/node_modules/ace-linters/build/ace-language-client.js:20613:18)
    at HoverTooltip.waitForHover (webpack-internal:///./node_modules/.pnpm/[email protected]/node_modules/ace-linters/build/ace-language-client.js:20370:18)
ProcessEmitWarning @ ace-language-client.js:2397
_addListener @ ace-language-client.js:2570
addListener @ ace-language-client.js:2578
postMessage @ ace-language-client.js:19453
doHover @ ace-language-client.js:19410
doHover @ ace-language-client.js:20700
eval @ ace-language-client.js:20618
waitForHover @ ace-language-client.js:20375
setTimeout (async)
onMouseMove @ ace-language-client.js:20364
EventEmitter._emit.EventEmitter._dispatchEvent @ ace.js:867
MouseHandler.onMouseMove @ ace.js:4314

Improve default configuration

  1. use moduleDetection: force to prevent error being shown when two files declare same const

     provider.setGlobalOptions("typescript", {
         compilerOptions: {
             moduleDetection: 3,
         }
     });
    
  2. automatically translate things like moduleDetection: "force" to moduleDetection: 3

  3. provide defualt values for warning/info error levels similar to cloud9.

Is SemanticToken support a possability?

Discussed in #104

Originally posted by Ryex March 17, 2024
I'm wondering if Semantic Token support is on the roadmap?

I'm currently working of a project to create an editor and emulator for an toy MIPS variant used as a scripting language in a game. that variant has a working LSP built by the community that I managed to get working via wasm in a webworker. The LSP has beautiful Semantic Token support but doesn't support highlighting. As such I've had to build my own highlighting rules. These rules can't capture the same context as the lsp though.

Incorrect sync mode in language client

It seems that the language client sends incremental changes when the server's capability is set to TextDocumentSyncKind.Full, and full changes when the server's capability is set to TextDocumentSyncKind.Incremental. I guess this boolean expression should be inverted.

image

As you can see from the Watch panel, the server has responded with the TextDocumentSyncKind.Incremental capability, but the function setValue is still called.

Feature Request: Make as Regular JavaScript Version (Sans NPM Requirement)

Is there any consideration to make a reglar browser JavaScript version of this than having to have NPPM? I've been trying to use this without NPM and so far haven't been able to figure out how to set it up as such (if even at all possible). I've also been looking into Browserify to convert this package to single file but am in very early stages of trying that.

Add support for R

Hi this is great is there anyway R support could be added for client side workloads.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.