summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml4
-rw-r--r--README.md84
-rw-r--r--src/lib.rs50
3 files changed, 54 insertions, 84 deletions
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,
 }