9 个版本
0.0.9 | 2020 年 12 月 27 日 |
---|---|
0.0.8 | 2019 年 7 月 25 日 |
0.0.7 | 2019 年 6 月 16 日 |
0.0.5 | 2018 年 3 月 12 日 |
0.0.1 | 2017 年 9 月 29 日 |
#249 in 文本编辑器
每月 45 次下载
110KB
2.5K SLoC
XRL (Xi Rpc Lib) 是 Xi RPC 的客户端实现。它用于构建 xi-tui。
它仍在开发中,但主要功能已经就位。
lib.rs
:
xrl
是一个基于 Tokio 的库,用于构建 Xi 编辑器的客户端。Xi RPC 的挑战在于端点既是客户端(发送请求/通知)又是服务器(处理传入请求/通知)。
extern crate futures;
extern crate tokio;
extern crate xrl;
use futures::{future, Future, Stream};
use xrl::*;
// Type that represent a `xi-core` peer. It implements `Frontend`,
// which means it can handle notifications and requests from
// `xi-core`.
#[allow(dead_code)]
struct MyFrontend {
// This is not actually used in this example, but if we wanted to
// our frontend could use a `Client` so that it could send
// requests and notifications to `xi-core`, instead of just
// handling incoming messages.
client: Client,
}
// Implement how our client handles notifications & requests from the core.
impl Frontend for MyFrontend {
type NotificationResult = Result<(), ()>;
fn handle_notification(&mut self, notification: XiNotification) -> Self::NotificationResult {
use XiNotification::*;
match notification {
Update(update) => println!("received `update` from Xi core:\n{:?}", update),
ScrollTo(scroll) => println!("received `scroll_to` from Xi core:\n{:?}", scroll),
DefStyle(style) => println!("received `def_style` from Xi core:\n{:?}", style),
AvailablePlugins(plugins) => {
println!("received `available_plugins` from Xi core:\n{:?}", plugins)
}
UpdateCmds(cmds) => println!("received `update_cmds` from Xi core:\n{:?}", cmds),
PluginStarted(plugin) => {
println!("received `plugin_started` from Xi core:\n{:?}", plugin)
}
PluginStoped(plugin) => {
println!("received `plugin_stoped` from Xi core:\n{:?}", plugin)
}
ConfigChanged(config) => {
println!("received `config_changed` from Xi core:\n{:?}", config)
}
ThemeChanged(theme) => println!("received `theme_changed` from Xi core:\n{:?}", theme),
Alert(alert) => println!("received `alert` from Xi core:\n{:?}", alert),
AvailableThemes(themes) => {
println!("received `available_themes` from Xi core:\n{:?}", themes)
}
FindStatus(status) => println!("received `find_status` from Xi core:\n{:?}", status),
ReplaceStatus(status) => {
println!("received `replace_status` from Xi core:\n{:?}", status)
}
AvailableLanguages(langs) => {
println!("received `available_languages` from Xi core:\n{:?}", langs)
}
LanguageChanged(lang) => {
println!("received `language_changed` from Xi core:\n{:?}", lang)
}
}
Ok(())
}
type MeasureWidthResult = Result<Vec<Vec<f32>>, ()>;
// we don't actually use the `request` argument in this example,
// hence the attribute.
#[allow(unused_variables)]
fn handle_measure_width(&mut self, request: MeasureWidth) -> Self::MeasureWidthResult {
Ok(Vec::new())
}
}
struct MyFrontendBuilder;
impl FrontendBuilder for MyFrontendBuilder {
type Frontend = MyFrontend;
fn build(self, client: Client) -> Self::Frontend {
MyFrontend { client }
}
}
fn init_xrl() {
tokio::run(future::lazy(move || {
// spawn Xi core
let (client, core_stderr) = spawn("xi-core", MyFrontendBuilder {}).unwrap();
// start logging Xi core's stderr
tokio::spawn(
core_stderr
.for_each(|msg| {
println!("xi-core stderr: {}", msg);
Ok(())
})
.map_err(|_| ()),
);
let client_clone = client.clone();
client
// Xi core expects the first notification to be
// "client_started"
.client_started(None, None)
.map_err(|e| eprintln!("failed to send \"client_started\": {:?}", e))
.and_then(move |_| {
let client = client_clone.clone();
client
.new_view(None)
.map(|view_name| println!("opened new view: {}", view_name))
.map_err(|e| eprintln!("failed to open a new view: {:?}", e))
.and_then(move |_| {
// Forces to shut down the Xi-RPC
// endoint. Otherwise, this example would keep
// running until the xi-core process
// terminates.
println!("shutting down");
client_clone.shutdown();
Ok(())
})
})
}));
}
依赖项
~9–17MB
~200K SLoC