< 返回版块

PrivateRookie 发表于 2022-02-13 15:10

Tags:lsp,parser,vscode

前段时间在用 rust 实现 vscode 的 lsp 服务, 虽然 ra 已经开发出了相关库, 但用着不是很舒服, 所以我自己弄了一个 LSP 相关的组件.

目前包含2个库

  • lsp-ty LSP 规范中提到的类型, 这些都是 rust 原生类型, 没有任何 binding, 以及一些辅助 trait
  • lsp-io 提供从 tcpstream 或 stdio 等读写协议消息的包装.

目前仓库还提供了一个简单 demo, 包含 vscode 插件lsp 实现.

相比于 ra 的用法, lsp-io 可以让你用类似 warp 组织路由的写法实现 LSP 服务, 以下代码来自 yaya-lsp

// pass handler function, you must specify param type
// in anonymous handler function argument, other wise
// you have to use turbo fish symbol
.then(|ctx, id, _: InitializeParams| {
    let ret = InitializeResult {
        capabilities: ServerCapabilities {
            completion_provider: Some(CompletionOptions {
                all_commit_characters: None,
                resolve_provider: None,
                trigger_characters: Some(vec!["$".to_string()]),
                work_done_progress: None,
            }),
            ..Default::default()
        },
        server_info: Some(InitializeResultServerInfo {
            name: "yaya-server".to_string(),
            version: Some("0.0.1".to_string()),
        }),
    };
    ctx.borrow_mut().resp(id.ok_resp(ret))
})
// use or_else to route to other handler function if
// method do not match
.or_else(|ctx, id, _: CompletionParams| {
    let item = CompletionItem {
        label: "demo".to_string(),
        detail: Some("that's ok".to_string()),
        insert_text: Some("yaya".to_string()),
        kind: Some(CompletionItemKind::Keyword),
        ..Default::default()
    };
    ctx.borrow_mut().resp(id.ok_resp(vec![item]))
})
.or_else(|ctx, id, _: ShutdownParams| {
    ctx.borrow_mut().terminated = true;
    tracing::info!("shutting down...");
    ctx.borrow_mut().resp(id.ok_resp(Empty {}))
})
// finally handle default req
.unify(|req| {
    let (req, ctx) = req.split();
    tracing::warn!("unhandled {:#?}", req);
    let mut ctx = ctx.borrow_mut();
    ctx.resp(req.id.ok_resp(serde_json::Value::Null))
})

实现效果如下

demo_lsp


项目地址


Ext Link: https://privaterookie.github.io/lsp-types/

评论区

写评论
作者 PrivateRookie 2022-02-19 23:19

现在支持异步了, 感兴趣的朋友可以查看 crates/io/examples 中的异步例子.

1 共 1 条评论, 1 页