4 个版本
0.3.2 | 2024 年 1 月 22 日 |
---|---|
0.3.1 | 2024 年 1 月 20 日 |
0.2.5 | 2024 年 1 月 18 日 |
#455 在 网络编程 中
每月 26 次下载
180KB
3K SLoC
Rust Hexchat API
这个库为 Hexchat 插件接口提供了 Rust API,并具有如下的 Rust 友好特性:
- 线程安全的 API。
- 简单的
user_data
对象。 - 如
Context
之类的抽象,使得与 UI 中的特定标签页/窗口交互变得简单。 - 在活动 Hexchat 窗口中捕获并显示恐慌。
- 调试构建包括恐慌的完整堆栈跟踪。
- 可以像普通函数或闭包一样实现钩子命令。
- 类型化首选项值和简单的插件首选项访问。
文档
文档可以在 这里 找到
示例
一个完成的插件提供了最多的示例。 这里有一个插件 可以进行自动翻译,使得可以与不同语言的人聊天(聊天时有字幕)。
使用 API 设置和注册命令很简单,语法清晰。
线程和 Hexchat 之间的交互通过 main_thread()
得以实现,它使用 Hexchat 的计时器事件循环来委派任务,例如将输出打印到活动 Hexchat 窗口。
hexchat.hook_command(
"runthread",
Priority::Norm,
|hc, word, word_eol, ud| {
// Grab a threadsafe version of the API.
let hcx = hc.threadsafe();
// Spawn a new thread.
thread::spawn(|| -> Result<(), HexchatError> {
// Send a task to the main thread to have executed and
// get its `AsyncResult` object.
let ares = main_thread(|hc| {
hc.print("Hello from main thread!");
"This is the return value from main!"
});
// Get the return data from the main thread callback.
// The call to `ares.get()` blocks.
let result = ares.get();
hc_print_th!("Spawned thread received from main \
thread: {}", result);
// Grab a threadsafe context to the currently focused
// channel.
let ctx = hcx.get_context();
// Get a threadsafe list iterator.
let user_list = hcx.list_get("users")?;
for user in user_list {
// Print user nicknames via the context object.
ctx.print(&user.get_field("nick")?.str())?;
}
Ok(())
});
Eat::All
},
"Runs a new thread that sets up a closure to run on the main \
thread.",
NoData);
链接到 hexchat_api
只需在 Rust 项目的 Cargo.toml
文件中包含一个条目
[dependencies]
hexchat-api = "0.3"
模板
以下代码可以复制以启动一个新的插件项目。TOML 文件内容也包含在下面。
// FILE: lib.rs
//! A starter project template that can be copied and modified.
use hexchat_api::*;
use UserData::*;
// Register the entry points of the plugin.
//
dll_entry_points!(plugin_info, plugin_init, plugin_deinit);
/// Called when the plugin is loaded to register it with Hexchat.
///
fn plugin_info() -> PluginInfo {
PluginInfo::new(
"Plugin Template",
"0.1",
"A Hexchat plugin to customize.")
}
/// Called when the plugin is loaded.
///
fn plugin_init(hc: &Hexchat) -> i32 {
hc.print("Plugin template loaded");
// Example user data to pass to a callback.
let udata = UserData::boxed("Some data to pass to a callback.");
// Register a simple command using a function.
hc.hook_command("HELLOWORLD",
Priority::Norm,
hello_world,
"Prints \"Hello, world!\"",
NoData);
// Register a simple command using a closure.
hc.hook_command("HELLOHEX",
Priority::Norm,
|hc, word, word_eol, user_data| {
hc.print("Hello, Hexchat!");
// Apply an operation to the string
// in the `UserData`.
user_data.apply(|msg: &&str| {
hc.print(msg);
});
Eat::All
},
"Prints \"Hello, Hexchat!\", \
and the user data.",
udata);
1
}
/// Called when the plugin is unloaded.
///
fn plugin_deinit(hc: &Hexchat) -> i32 {
hc.print("Plugin template unloaded");
1
}
/// A command callback implemented as a function.
/// # Arguments
/// * `hc` - The Hexchat API object reference.
/// * `word` - A list of parameters passed to the command.
/// * `word_eol` - Like `word`, but catenates the word args
/// decrementally.
/// * `user_data` - The user data to be passed back to the command
/// when invoked by Hexchat.
/// # Returns
/// * One of `Eat::All`, `Eat::Hexchat`, `Eat::Plugin`, `Eat::None`.
///
fn hello_world(hc : &Hexchat,
word : &[String],
word_eol : &[String],
user_data : &UserData
) -> Eat
{
hc.print("Hello, world!");
Eat::All
}
以及 Cargo.toml 文件。
[package]
name = "hexchat_plugin_template"
version = "0.1.0"
authors = ["you <[email protected]>"]
edition = "2021"
[lib]
name = "hexchat_plugin_template"
crate-type = ["cdylib"]
[dependencies]
hexchat-api = "0.3"
依赖项
~2.4–3.5MB
~72K SLoC