diff --git a/Cargo.toml b/Cargo.toml
index b7fb2aa..bab4aa6 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,10 +1,10 @@
[package]
name = "hexchat-plugin"
-version = "0.2.13"
+version = "0.2.14"
authors = ["SoniEx2 <endermoneymod@gmail.com>"]
description = "Lets you write HexChat plugins in Rust"
license = "AGPL-3.0+"
-repository = "https://cybre.tech/SoniEx2/rust.hexchat.hexchat-plugin"
+repository = "https://soniex2.autistic.space/git-repos/hexchat-plugin.git"
homepage = "https://ganarchy.autistic.space/project/7597bdc9d42badc332ecd57ab81e71c41fa2b595"
keywords = ["hexchat", "plugin", "hexchat-plugin"]
categories = ["api-bindings"]
diff --git a/README.md b/README.md
index 78bd3cd..9effee2 100644
--- a/README.md
+++ b/README.md
@@ -1,70 +1,40 @@
Rust hexchat-plugin
===================
-`hexchat-plugin` provides safe and rusty API bindings for developing native HexChat plugins.
+`hexchat-plugin` provides safe and rusty API bindings for developing native
+HexChat plugins.
-Example plugin:
+To get started, implement `hexchat_plugin::Plugin` on a struct and use the
+`hexchat_plugin!(impl Plugin)` macro in your `lib.rs`. Do not provide a `main`,
+as it will not work. Make sure to use the `cdylib` crate-type, or it will also
+not work.
-```rust
-#[macro_use]
-extern crate hexchat_plugin;
+Also note that plugins may be loaded multiple times. It's recommended to avoid
+using global state (statics, thread locals) so as to not cause issues with it.
-use hexchat_plugin::{Plugin, PluginHandle, InfoId};
+Examples
+--------
-use std::sync::Mutex;
-use std::sync::Arc;
+For a production-grade plugin using this crate, take a look at
+<https://github.com/SoniEx2/cw2-hexchat>.
-#[derive(Default)]
-struct MyPlug {
- // be careful with these: we don't want to move them into the hooks, as that would cause memory leaks!
- // we can safely use Arc::downgrade on them, however!
- cmutex: Arc<Mutex<Vec<hexchat_plugin::CommandHookHandle>>>,
- smutex: Arc<Mutex<Vec<hexchat_plugin::ServerHookHandle>>>,
- pmutex: Arc<Mutex<Vec<hexchat_plugin::PrintHookHandle>>>,
- tmutex: Arc<Mutex<Vec<hexchat_plugin::TimerHookHandle>>>,
-}
+License
+-------
+```text
+Hexchat Plugin API Bindings for Rust
+Copyright (C) 2018, 2021 Soni L.
-impl Plugin for MyPlug {
- fn init(&self, ph: &mut PluginHandle, _arg: Option<&str>) -> bool {
- ph.register("MyPlug", "Prints the old topic on topic change", "0.1.0");
- ph.print("Loaded MyPlug 0.1.0");
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
- let enabled = Arc::new(Mutex::new(false));
- {
- let flag = enabled.clone();
- self.pmutex.lock().unwrap().push(ph.hook_print("Topic Change", move |ph, _word| {
- if *flag.lock().unwrap() {
- if let Some(topic) = ph.get_info(&InfoId::Topic) {
- ph.print(&format!("\x0322*\t\x0329Previous topic:\x03 {}", topic));
- }
- }
- hexchat_plugin::EAT_NONE
- }, hexchat_plugin::PRI_NORM));
- }
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
- self.cmutex.lock().unwrap().push(ph.hook_command("PrintOldTopic", move |ph, _word, word_eol| {
- match word_eol.get(1) {
- Option::Some(&s) if s == "true" => {
- ph.print("Set PrintOldTopic to true");
- *enabled.lock().unwrap() = true;
- }
- Option::Some(&s) if s == "false" => {
- ph.print("Set PrintOldTopic to false");
- *enabled.lock().unwrap() = false;
- }
- Option::Some(_) => {
- ph.print("Usage: /PrintOldTopic [true|false]");
- }
- Option::None => {
- ph.print(&format!("PrintOldTopic: {}", *enabled.lock().unwrap()));
- }
- }
- hexchat_plugin::EAT_ALL
- }, hexchat_plugin::PRI_NORM, Some("Usage: /PrintOldTopic [true|false]")));
- true // tells hexchat we have successfully initialized
- }
-}
-
-hexchat_plugin!(MyPlug);
+You should have received a copy of the GNU Affero General Public License
+along with this program. If not, see <https://www.gnu.org/licenses/>.
```
diff --git a/src/lib.rs b/src/lib.rs
index 444753e..465ff5e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,20 +1,19 @@
-/*
- * Hexchat Plugin API Bindings for Rust
- * Copyright (C) 2018 Soni L.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
+// Hexchat Plugin API Bindings for Rust
+// Copyright (C) 2018, 2021 Soni L.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
+
//! Write hexchat plugins in Rust!
//!
//! This library provides safe API bindings for hexchat, but doesn't attempt to fix hexchat's own
@@ -954,9 +953,10 @@ impl PluginHandle {
/// Prints to the hexchat buffer.
// this checks the context internally. if it didn't, it wouldn't be safe to have here.
- pub fn print(&mut self, s: &str) {
+ pub fn print<T: ToString>(&mut self, s: T) {
+ let s = s.to_string();
unsafe {
- hexchat_print_str(self.ph, s, true);
+ hexchat_print_str(self.ph, &*s, true);
}
}
@@ -1186,7 +1186,7 @@ impl<'a> EnsureValidContext<'a> {
/// Prints to the hexchat buffer.
// as of hexchat 2.14.1, this does not call hooks.
- pub fn print(&mut self, s: &str) {
+ pub fn print<T: ToString>(&mut self, s: T) {
self.ph.print(s)
}
@@ -1222,13 +1222,13 @@ impl<'a> EnsureValidContext<'a> {
// mutable state, std provides std::sync::Mutex which has poisoning. Other interior mutability with
// poisoning could also be used. std doesn't have anything for single-threaded performance (yet),
// but hexchat isn't particularly performance-critical.
-type CommandHookUd = (Box<Fn(&mut PluginHandle, Word, WordEol) -> Eat + ::std::panic::RefUnwindSafe>, *mut internals::Ph, PluginInfo);
+type CommandHookUd = (Box<dyn Fn(&mut PluginHandle, Word, WordEol) -> Eat + ::std::panic::RefUnwindSafe>, *mut internals::Ph, PluginInfo);
/// Userdata type used by a server hook.
-type ServerHookUd = (Box<Fn(&mut PluginHandle, Word, WordEol, EventAttrs) -> Eat + ::std::panic::RefUnwindSafe>, *mut internals::Ph, PluginInfo);
+type ServerHookUd = (Box<dyn Fn(&mut PluginHandle, Word, WordEol, EventAttrs) -> Eat + ::std::panic::RefUnwindSafe>, *mut internals::Ph, PluginInfo);
/// Userdata type used by a print hook.
-type PrintHookUd = (Box<Fn(&mut PluginHandle, Word, EventAttrs) -> Eat + ::std::panic::RefUnwindSafe>, *mut internals::Ph, PluginInfo);
+type PrintHookUd = (Box<dyn Fn(&mut PluginHandle, Word, EventAttrs) -> Eat + ::std::panic::RefUnwindSafe>, *mut internals::Ph, PluginInfo);
/// Userdata type used by a timer hook.
-type TimerHookUd = (Rc<(Box<Fn(&mut PluginHandle) -> bool + ::std::panic::RefUnwindSafe>, *mut internals::Ph, PluginInfo)>, Rc<Cell<bool>>);
+type TimerHookUd = (Rc<(Box<dyn Fn(&mut PluginHandle) -> bool + ::std::panic::RefUnwindSafe>, *mut internals::Ph, PluginInfo)>, Rc<Cell<bool>>);
/// The contents of an empty CStr.
///
@@ -1393,7 +1393,7 @@ impl PluginInfo {
/// Plugin data stored in the hexchat plugin_handle.
struct PhUserdata {
- plug: Box<Plugin>,
+ plug: Box<dyn Plugin>,
pluginfo: PluginInfo,
}
|