vscode-languageserver-csharp-example

(https://github.com/matarillo/vscode-languageserver-csharp-example “vscode-languageserver-csharp-example”)

Client

客户端用于设置选项,激活插件并启动语言服务器。

服务端选项
let serverOptions: ServerOptions =
        (os.platform() === 'win32') ? {
            run : <Executable>{ command: serverCommand, options: commandOptions },
            debug: <Executable>{ command: serverCommand, options: commandOptions }
        } : {
            run : <Executable>{ command: 'mono', args: [serverCommand], options: commandOptions },
            debug: <Executable>{ command: 'mono', args: [serverCommand], options: commandOptions }
        };
客户端选项
let clientOptions: LanguageClientOptions = {
        // 为文本文档注册语言服务器
        documentSelector: ['plaintext'],
        synchronize: {
            // 同步设置到语言服务器
            configurationSection: 'languageServerExample',
            // 告知服务器工作区中clientrc文件的更改
            fileEvents: workspace.createFileSystemWatcher('**/.clientrc')
        }
    };
新建客户端、设置服务端并启动
client = new LanguageClient(
        'languageServerExample',
        'Language Server Example',
        serverOptions,
        clientOptions
    );

    // 启动客户端,同时启动服务端
    client.start();

Server

服务器的工作主要为监听文件变化,接收用户行为信息,返回响应信息。

初始化(Initialize)

“`c#
protected override Result<InitializeResult, ResponseError<InitializeErrorData>> Initialize(InitializeParams @params)
{
_workerSpaceRoot = @params.rootUri;
var result = new InitializeResult
{
capabilities = new ServerCapabilities
{
textDocumentSync = TextDocumentSyncKind.Full,
completionProvider = new CompletionOptions
{
resolveProvider = true
}
}
};
return Result<InitializeResult, ResponseError<InitializeErrorData>>.Success(result);
}

<pre><code class="line-numbers">[![](https://adobie.top/wp-content/uploads/2022/09/wp_editor_md_9675f44ee44eed21c024032ecb3fbda4.jpg)](https://adobie.top/wp-content/uploads/2022/09/wp_editor_md_9675f44ee44eed21c024032ecb3fbda4.jpg)

在库中的定义:

“`c#
public class InitializeParams
{
/// <summary>
/// The process Id of the parent process that started the server.
/// </summary>
public int? processId { get; set; }

/// <summary>
/// The rootUri of the workspace.
/// </summary>
public Uri rootUri { get; set; }

/// <summary>
/// User provided initialization options.
/// </summary>
public dynamic initializationOptions { get; set; }

/// <summary>
/// The capabilities provided by the client (editor or tool)
/// </summary>
public ClientCapabilities capabilities { get; set; }

/// <summary>
/// The initial trace setting.
/// </summary>
/// <remarks>
/// If omitted trace is disabled (‘off’).
/// </remarks>
/// <value>
/// See <see cref=”LanguageServer.Parameters.TraceKind”/> for an enumeration of standardized kinds.
/// </value>
/// <seealso cref=”LanguageServer.Parameters.TraceKind”/>
public string trace { get; set; }

/// <summary>
/// The workspace folders configured in the client when the server starts.
/// </summary>
/// <remarks>
/// This property is only available if the client supports workspace folders.
/// It can be <c>null</c> if the client supports workspace folders but none are
/// configured.
/// </remarks>
/// <seealso>Spec 3.6.0</seealso>
public WorkspaceFolder[] workspaceFolders { get; set; }
}

打开文件(DidOpenTextDocument)

“`C#
protected override void DidOpenTextDocument(DidOpenTextDocumentParams @params)
{
_documents.Add(@params.textDocument);
Logger.Instance.Log($"{@params.textDocument.uri} opened.");
}

<pre><code class="line-numbers">在库中的定义:

“`C#
public class DidOpenTextDocumentParams
{
public TextDocumentItem textDocument { get; set; }
}

其中,textDocument的定义如下:

“`C#
public class TextDocumentItem
{
public Uri uri { get; set; }

<pre><code> public string languageId { get; set; }

public long version { get; set; }

public string text { get; set; }
}
</code></pre>

<pre><code class="line-numbers">##### 编辑文件(DidChangeTextDocument)

“`C#
protected override void DidChangeTextDocument(DidChangeTextDocumentParams @params)
{
_documents.Change(@params.textDocument.uri, @params.textDocument.version, @params.contentChanges);
Logger.Instance.Log($”{@params.textDocument.uri} changed.”);
}

在库中的定义:

“`C#
public class DidChangeTextDocumentParams
{
public VersionedTextDocumentIdentifier textDocument { get; set; }

<pre><code> public TextDocumentContentChangeEvent[] contentChanges { get; set; }
}
</code></pre>

<pre><code class="line-numbers">其中**VersionedTextDocumentIdentifier**的定义如下:

“`C#
public class VersionedTextDocumentIdentifier : TextDocumentIdentifier
{
public long version { get; set; }
}

其中TextDocumentContentChangeEvent的定义如下:

“`C#
public class TextDocumentContentChangeEvent
{
public Range range { get; set; }

<pre><code> public long? rangeLength { get; set; }

public string text { get; set; }
}
</code></pre>

<pre><code class="line-numbers">##### 关闭文件(DidCloseTextDocument)

“`C#
protected override void DidCloseTextDocument(DidCloseTextDocumentParams @params)
{
_documents.Remove(@params.textDocument.uri);
Logger.Instance.Log($”{@params.textDocument.uri} closed.”);
}

在库中的定义:

“`C#
public class DidCloseTextDocumentParams
{
public TextDocumentIdentifier textDocument { get; set; }
}

<pre><code class="line-numbers">其中**TextDocumentIdentifier**的定义如下:

“`C#
public class TextDocumentIdentifier
{
public Uri uri { get; set; }
}

以上函数都与C#中的特性进行绑定,从而控制调用时机。库中自定义特性如下:

“`C#
[AttributeUsage(AttributeTargets.Method)]
public class JsonRpcMethodAttribute : Attribute
{
private string _method;

<pre><code> public JsonRpcMethodAttribute(string method)
{
_method = method;
}

public string Method
{
get => _method;
}
}
</code></pre>

<pre><code class="line-numbers">特性应用如下:

“`C#
[JsonRpcMethod(“initialize”)]
protected virtual Result<InitializeResult, ResponseError<InitializeErrorData>> Initialize(InitializeParams @params)
{
throw new NotImplementedException();
}

[JsonRpcMethod(“textDocument/didOpen”)]
protected virtual void DidOpenTextDocument(DidOpenTextDocumentParams @params)
{
}

[JsonRpcMethod(“textDocument/didChange”)]
protected virtual void DidChangeTextDocument(DidChangeTextDocumentParams @params)
{
}
[JsonRpcMethod(“textDocument/didClose”)]
protected virtual void DidCloseTextDocument(DidCloseTextDocumentParams @params)
{
}

自动补全及语法检测等

先根据事件处理委托构建编辑事件:

“`C#
public event EventHandler<TextDocumentChangedEventArgs> Changed;

<pre><code class="line-numbers">之后构造触发事件的函数:

“`C#
protected virtual void OnChanged(TextDocumentItem document)
{
Changed?.Invoke(this, new TextDocumentChangedEventArgs(document));
}

再新建该事件所在类的对象,并对该事件设置触发时所执行的函数:

“`C#
public App(Stream input, Stream output)
: base(input, output)
{
_documents = new TextDocumentManager();
_documents.Changed += Documents_Changed;
}

<pre><code class="line-numbers">其中**Documents_Changed**定义如下:

“`C#
private void Documents_Changed(object sender, TextDocumentChangedEventArgs e)
{
ValidateTextDocument(e.Document);
}

ValidateTextDocument

监听和等待(Listen&Wait)

“`C#
try
{
app.Listen().Wait();
}
catch (AggregateException ex)
{
Console.Error.WriteLine(ex.InnerExceptions[0]);
Environment.Exit(-1);
}
“`

其中ListenWait函数直接使用库中定义。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇